Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js MongoDB-OneToMany,在child中使用外键_Node.js_Mongodb_Mongoose_Reverse_Populate - Fatal编程技术网

Node.js MongoDB-OneToMany,在child中使用外键

Node.js MongoDB-OneToMany,在child中使用外键,node.js,mongodb,mongoose,reverse,populate,Node.js,Mongodb,Mongoose,Reverse,Populate,我正在使用mongodb v.2.6.11和mongoose 我有两个模特,一对一。在我的父母TypeA(缩写为TA)中,我没有提到孩子。在我的孩子TypeB(缩写为TB)中,我有一个指向父母的id引用 模式示例: var TASchema = { name: {type: String, required: "TASchema.name is required", index: {unique: true, dropDups: true}} }; var TBSchema =

我正在使用mongodb v.2.6.11和mongoose

我有两个模特,一对一。在我的父母TypeA(缩写为TA)中,我没有提到孩子。在我的孩子TypeB(缩写为TB)中,我有一个指向父母的id引用

模式示例:

var TASchema = {
    name: {type: String, required: "TASchema.name is required", index: {unique: true, dropDups: true}}
}; 

var TBSchema  = {
    start: {type: Number, required: "TBSchema.language is required"},
    stop: {type: Number, required: "TBSchema.stop is required"},
    TA: {type: Schema.Types.ObjectId, ref: 'tbschema'},
}
我要做的是:选择在两个变量“tsu start”和“tsu stop”(它们是时间戳)的时间跨度内具有“start”变量的所有TB。比如:
start:{$gte:ts_min,$lte:ts_max}

示例输出:

[
    {
       name: "Ta object 1",
       tbs: [{start : 1, stop2}, {start: 2, stop: 3}] 
    },
    {
       name: "Ta object 2",
       tbs: [{start : 1, stop2}, {start: 2, stop: 3}] 
    }
]
我希望保留查询返回一个TA数组的结构,其中每个TA都包含一个TB:s数组。但是我不能使用
填充
,因为TA没有对子文档的任何引用(因为太多了,无法将它们作为子文档保存)


那么这是如何实现的呢?我是不是想错了,或者我应该怎么做才能像我的示例输出那样输出指定的查询?

要借助@vmkcom,请尝试聚合框架,通过管道步骤来实现这一点,使用管道操作返回的结果填充TA字段,但TA模型的架构设计有所改变。这是填充聚合结果所必需的,因此在TA架构中为TB架构添加一个引用数组:

var TASchema = {
    name: { 
        type: String, 
        required: "TASchema.name is required", 
        index: {unique: true, dropDups: true}
    },
    tbs: [{ type: Schema.Types.ObjectId, ref: 'tbschema' }]
};
实现类似以下内容(未经测试):


使用填充TA按给定标准选择TB文档。通过按TA分组,重新格式化TBs的响应数组。您可以尝试使用$group request来实现这一点,但使用javascript处理文档更容易,请求速度更快。这几乎是完美的。但是如何将TBA(例如名称)中的数据填充到聚合对象中?@VictorAxelsson尚未对其进行测试,但您可以使用TBModel上的填充方法从TA中填充数据,如答案所示。更多关于。我不太了解路径的作用,以及我如何将TA的名称包括在“外部”对象(具有TB:s数组)中。填充方法中的路径选项指的是要填充的路径,即填充的路径不再设置为其原始的
\u id
,通过在返回结果之前在引擎盖下执行单独的查询,将它们的值替换为从数据库返回的mongoose文档。如果您只希望为填充的文档返回TA的名称,可以通过将字段名语法作为第二个参数中的
select
属性值传递给populate方法来实现。我不知道为什么,但populate函数似乎没有为我做任何事情。无论我在路径值中输入什么,都不会发生任何事情,select也不会做任何事情。如果在TA或TB上使用populate,则没有区别。
var pipeline = [
    { 
        "$match": { 
            "start": { "$gte": ts_min, "$lte": ts_max }
        }
    },
    { 
        "$group": {
            "_id": "$TA",
            "tbs": {
                "$push": {  "start": "$start", "stop": "$stop" }
            }           
        }
    }
];
TBModel.aggregate(pipeline,
    function(err, results) {
        if (err) throw err; 
        var results = result.map(function(doc) { return new TAModel(doc) });        
        TBModel.populate(results, {"path": "TA"}, function(err, docs) {
            if (err) throw err;
            console.log(JSON.stringify(docs, undefined, 4));
        });
    }
);