Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.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
Javascript 猫鼬_Javascript_Node.js_Mongodb_Mongoose_Nosql - Fatal编程技术网

Javascript 猫鼬

Javascript 猫鼬,javascript,node.js,mongodb,mongoose,nosql,Javascript,Node.js,Mongodb,Mongoose,Nosql,我使用Mongoose.js,无法解决三级层次结构文档的问题 有两种方法可以做到这一点 首先-无参考文献 C = new Schema({ 'title': String, }); B = new Schema({ 'title': String, 'c': [C] }); A = new Schema({ 'title': String, 'b': [B] }); 我需要显示C记录。我如何填充/找到它,只知道C的id 我尝试使用: A.findOn

我使用Mongoose.js,无法解决三级层次结构文档的问题

有两种方法可以做到这一点

首先-无参考文献

C = new Schema({
    'title': String,
});

B = new Schema({
    'title': String,
    'c': [C]
});

A = new Schema({
    'title': String,
    'b': [B]
});
我需要显示C记录。我如何填充/找到它,只知道C的id

我尝试使用:

A.findOne({'b.c._id': req.params.c_id}, function(err, a){
    console.log(a);
});
但是我不知道如何从returnet中获取一个对象,只获取我需要的c对象

第二个如果使用参照:

C = new Schema({
    'title': String,
});

B = new Schema({
    'title': String,
    'c': [{ type: Schema.Types.ObjectId, ref: 'C' }]
});

A = new Schema({
    'title': String,
    'b': [{ type: Schema.Types.ObjectId, ref: 'B' }]
});
如何填充所有B、C记录以获得层次结构

我试着用这样的东西:

A
.find({})
.populate('b')
.populate('b.c')
.exec(function(err, a){
    a.forEach(function(single_a){
        console.log('- ' + single_a.title);
        single_a.b.forEach(function(single_b){
            console.log('-- ' + single_b.title);
            single_b.c.forEach(function(single_c){
                console.log('--- ' + single_c.title);
            });
        });
    });
});
A.deepPopulate(docs, 'b.c', {
  b: { 
    select: 'name'
  }
}, cb)
但它将返回未定义的单c标题。我有办法填充它吗


谢谢。

在Mongoose 4中,您可以跨多个级别填充文档:

假设您有一个用户模式,该模式跟踪用户的朋友

var userSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});
首先,
populate()
允许您获取用户好友列表。但是如果你也想要一个用户的朋友的朋友呢?在这种情况下,您可以指定一个
填充
选项,告诉mongoose填充所有用户朋友的
朋友
数组:

User.
  findOne({ name: 'Val' }).
  populate({
    path: 'friends',
    // Get friends of friends - populate the 'friends' array for every friend
    populate: { path: 'friends' }
  });
摘自:

自Mongoose 3.6起,已添加查询中的。下面是一个示例,说明您可以如何执行此操作:

 UserList.findById(listId)
         .populate('refUserListItems')
         .exec(function(err, doc){
             UserListItem.populate(doc.refUserListItems, {path:'refSuggestion'},
                   function(err, data){
                        console.log("User List data: %j", doc);
                        cb(null, doc);
                   }
             );     
          });           
在本例中,我使用引用的文档填充“RefuerListItems”中的id数组。然后,查询结果被传递到另一个填充查询中,该查询引用了我要填充的原始填充文档的字段—“refSuggestion”

注意第二个(内部)填充-这就是神奇发生的地方。您可以继续嵌套这些填充并添加越来越多的文档,直到按照需要的方式构建图形为止


理解它是如何工作的需要一点时间,但如果你能理解它,它是有意义的。

我做得晚了,但我写了一篇文章,这使得执行深度模型填充非常简单。例如,您可以这样做来填充
b
c

A.find({}, function (err, docs) {
  A.deepPopulate(docs, 'b.c', cb)
}
还可以为每个填充的路径指定,如下所示:

A
.find({})
.populate('b')
.populate('b.c')
.exec(function(err, a){
    a.forEach(function(single_a){
        console.log('- ' + single_a.title);
        single_a.b.forEach(function(single_b){
            console.log('-- ' + single_b.title);
            single_b.c.forEach(function(single_c){
                console.log('--- ' + single_c.title);
            });
        });
    });
});
A.deepPopulate(docs, 'b.c', {
  b: { 
    select: 'name'
  }
}, cb)

查看插件以了解更多信息。

在Mongoose 4中,您可以像这样填充多级(即使在不同的数据库或实例中)


aaron对类似问题的回答与FYI相同-这已在版本3.6中得到解决-@BoxerBucks您能提供一个示例吗?(参考文献案例)@fusio-我添加了一个答案,作为一个例子,说明我没有理由否决这个答案,因为现在这个答案无效@GianPaJ更新您的答案,而不是删除。如果支持,最好选择一个新的接受答案。这是可行的,但上面Buu Nguyen给出的深度填充更方便。无需执行嵌套循环..如何使用Promissions执行此操作?@steampowered-哪部分?您可以将整个过程封装在一个函数中,该函数返回一个承诺,并在回调中解析该承诺到.populate。它看起来像是.populate还返回了一个承诺,这样您就可以在.populate函数中的任何一个上捕获这个承诺,然后调用.foullate,当您想运行它时再调用它。@BoxerBucks我决定返回
.populate()
函数链中返回的承诺。然后()
函数,最后用最后一个
函数运行它。然后()
。我认为这看起来比筑巢n水平的种群更干净。如果我必须查找文档,而不是单个文档,我应该迭代每个文档来填充内部路径,还是有一种方法可以在所有文档上进行填充呢?这看起来非常酷。当它变得更成熟时,我可能会在生产中使用它。b:ment不是应该是c:?这肯定应该标记为正确答案+1A小偏差。。如果
B=newschema({'title':String,'c':[{type:Schema.Types.ObjectId,ref'c'}],'cc':[{type:Schema.Types.ObjectId,ref'c'}])如何同时填充c和cc?您可以这样做。填充('c')。在链中填充('cc')这样填充。这就是你想要的吗?甚至是B.populate([{path:'c'},{path:'cc'}]))