【问题标题】:Mongoose populate nested arrayMongoose 填充嵌套数组
【发布时间】:2015-03-26 14:43:00
【问题描述】:

假设以下3个模型:

var CarSchema = new Schema({
  name: {type: String},
  partIds: [{type: Schema.Types.ObjectId, ref: 'Part'}],
});

var PartSchema = new Schema({
  name: {type: String},
  otherIds: [{type: Schema.Types.ObjectId, ref: 'Other'}],
});

var OtherSchema = new Schema({
  name: {type: String}
});

当我查询 Cars 时,我可以填充零件:

Car.find().populate('partIds').exec(function(err, cars) {
  // list of cars with partIds populated
});

猫鼬有没有办法在所有汽车的嵌套零件对象中填充 otherIds。

Car.find().populate('partIds').exec(function(err, cars) {
  // list of cars with partIds populated
  // Try an populate nested
  Part.populate(cars, {path: 'partIds.otherIds'}, function(err, cars) {
    // This does not populate all the otherIds within each part for each car
  });
});

我可能会遍历每辆车并尝试填充:

Car.find().populate('partIds').exec(function(err, cars) {
  // list of cars with partIds populated

  // Iterate all cars
  cars.forEach(function(car) {
     Part.populate(car, {path: 'partIds.otherIds'}, function(err, cars) {
       // This does not populate all the otherIds within each part for each car
     });
  });
});

问题是我必须使用像 async 这样的库来为每个库进行填充调用,然后等到所有操作都完成然后返回。

可以不循环遍历所有汽车吗?

【问题讨论】:

    标签: node.js mongodb mongoose mongoose-populate


    【解决方案1】:

    应该会更好

    Car
    .find()
    .populate({
        path: 'partIds.othersId'
    })
    

    【讨论】:

      【解决方案2】:

      更新:请参阅Trinh Hoang Nhu's answer,了解在 Mongoose 4 中添加的更紧凑的版本。总结如下:

      Car
        .find()
        .populate({
          path: 'partIds',
          model: 'Part',
          populate: {
            path: 'otherIds',
            model: 'Other'
          }
        })
      

      Mongoose 3 及以下:

      Car
        .find()
        .populate('partIds')
        .exec(function(err, docs) {
          if(err) return callback(err);
          Car.populate(docs, {
            path: 'partIds.otherIds',
            model: 'Other'
          },
          function(err, cars) {
            if(err) return callback(err);
            console.log(cars); // This object should now be populated accordingly.
          });
        });
      

      对于像这样的嵌套人口,您必须告诉 mongoose 您要从中填充的 Schema。

      【讨论】:

      • 废话 RTFM ;) 我现在明白了。但是,无论我尝试什么,我都会为 otherIds 返回一个空数组。作为健全性检查,如果我不调用 populate 方法,则会有一个 id 数组(这是正确的)。填充没有填充这些 id。从 npm 运行最新的 3.8.22
      • 还开启了日志记录。我没有看到另一个调用另一个集合来填充“加入”。所以猫鼬甚至没有打电话。
      • @lostintranslation 在嵌套的populate 调用中应该是model: 'Other'
      • @JohnnyHK 再次救援,谢谢!作为旁注,虽然我可能能够在第一次调用 Car.find().populate('partIds').populate({path: 'partIds.otherIds', model: 'Other').exec 时得到它。 .. 不走运,您必须先进行第一次查询调用才能填充 partIds。
      • 或者,您可以尝试mongoose-deep-populate plugin 并用Car.find().deepPopulate('partIds.otherIds').exec(...) 重写整个内容。 (免责声明:我是作者。)
      【解决方案3】:

      使用mongoose deepPopulate plugin

      car.find().deepPopulate('partIds.otherIds').exec();
      

      【讨论】:

        【解决方案4】:

        Mongoose 4 支持这个

        Car
        .find()
        .populate({
          path: 'partIds',
          model: 'Part',
          populate: {
            path: 'otherIds',
            model: 'Other'
          }
        })
        

        【讨论】:

        • 注意:型号:“其他”是必需的。没有它,它会给出空数组。文档没有指定它:mongoosejs.com/docs/populate.html#deep-populate
        • 但我想在一个嵌套级别中进行双重填充。所以基本上像下面这样, Car .find() .populate({ path: 'partIds', model: 'Part', populate: { path: 'otherIds', model: 'Other' } populate: { path: 'ModelIds' , 型号: '型号' } })
        猜你喜欢
        • 2020-06-07
        • 2019-12-06
        • 2018-06-07
        • 2016-10-12
        • 2019-09-23
        • 1970-01-01
        • 2016-03-01
        • 2017-03-01
        相关资源
        最近更新 更多