32

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

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

首先- 没有参考。

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 对象。

其次,如果使用 refs:

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);
            });
        });
    });
});

但它会为 single_c.title 返回 undefined。我有办法填充它吗?

谢谢。

4

4 回答 4

43

从 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);
                   }
             );     
          });           

在这种情况下,我在 'refUserListItems' 中用他们引用的文档填充了一个 id 数组。然后,查询的结果被传递到另一个填充查询,该查询引用我想要填充的原始填充文档的字段 - 'refSuggestion'。

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

需要一点时间来消化它是如何工作的,但如果你通过它,它是有道理的。

于 2013-08-14T15:11:38.880 回答
34

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

A
.find({})
.populate({
  path: 'b', 
  model: 'B',
  populate: {
    path: 'c',
    model: 'C'
  }
})
.exec(function(err, a){});
于 2015-12-23T22:22:01.910 回答
31

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

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

var userSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});

首先populate()让您获得用户朋友列表。但是,如果您还想要用户的朋友的朋友怎么办?在这种情况下,您可以指定一个populate选项来告诉 mongoose 填充friends所有用户朋友的数组:

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

取自: http: //mongoosejs.com/docs/populate.html#deep-populate

于 2012-10-31T17:44:31.463 回答
5

我迟到了,但我写了一个Mongoose 插件,它使得执行深度模型填充变得非常简单。对于您的示例,您可以这样做来填充bc

A.find({}, function (err, docs) {
  A.deepPopulate(docs, 'b.c', cb)
}

您还可以为每个填充路径指定Mongoose 填充选项,如下所示:

A.deepPopulate(docs, 'b.c', {
  b: { 
    select: 'name'
  }
}, cb)

查看插件文档以获取更多信息。

于 2014-12-10T19:44:06.640 回答