繁体   English   中英

Mongoose - 在对象中填充对象

[英]Mongoose - Populate object in object

假设我有3 个模型

// Parent
const ParentSchema = new Schema({
    child: {
        type: ObjectId,
        ref: 'Child'
    },

    ...
});

// Child
const ChildSchema = new Schema({
    subChild: {
        type: ObjectId,
        ref: 'SubChild'
    },

    ...
});

// SubChild
const SubChildSchema = new Schema({
    name: String,
    ...
});

我在Parent上使用findOne ,我想在Child上使用populate ,但也在SubChildSubChild

Parent.findOne(options)
    .populate('child', 'subChild')
    // Trying to add another populate on subChild property like : .populate('<above_subChild>', 'name')
    .select('child')
    .exec(function (err, parent) {
        callback(err, parent.toJSON());
    })
;

有没有办法用populate做到这一点?


目前, parent.toJSON()返回:

{
    // Parent _id
    _id: XXX,
    child: {
        _id: XXX,
        subChild: <subChild_ObjectID>        
    }
}

下面是我想要通过在subChild属性上添加另一个populatesubChild是:

{
    // Parent _id
    _id: XXX,
    child: {
        _id: XXX,
        subChild: {
            _id: XXX,
            name: XXX
        }
    }
}

这也将起作用:

Parent.findOne(options)
  .select('child')
  .populate('child.subChild')
  .exec(function(err, parent) {
    callback(err, parent.toJSON());
  });

参考populate的文档,该查询需要按如下方式构建以填充多个级别:

Parent.findOne(options)
  .populate({
    path: 'child',
    populate: {
      path: 'subChild'
    }
  })
  .select('child')
  .exec(function(err, parent) {
    callback(err, parent.toJSON());
  });

使用 mongoose 的populate方法需要注意的一件事是每个种群都需要一个单独的查询。 所以在这种情况下,虽然实现使用了一个显式的findOne方法,但 mongoose 实际上是连续执行三个查询。

这大致相当于(稍微伪编码):

Parent.findOne().exec().then((parent) => ([
  parent,
  Child.findById(parent.child).exec()
])).then(([parent, child]) => ([
  parent,
  child,
  SubChild.findById(child.subChild).exec()
])).then(([parent, child, subChild]) => {
  child.subChild = subChild;
  parent.child = child;

  return parent;
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM