【问题标题】:Mongoose nested reference population猫鼬嵌套参考种群
【发布时间】:2016-07-02 17:20:56
【问题描述】:

我无法理解 mongoose 的 populate 方法背后的一些概念。我首先使用了一种嵌入式方法,但由于担心数据和不同步文档的大量开销,我尝试将范例更改为 ref 其他文档。

我的 Schema 类似于以下(删除了不相关的属性):

var userSchema = mongoose.Schema({
    name: {type: String, default:''},
    favorites:{ 
        users:[{type: Schema.Types.ObjectId, ref: this}],
        places:[{type: Schema.Types.ObjectId, ref: PlaceSchema}]
    }
});

module.exports = mongoose.model('User', userSchema);

现在我正在尝试像这样获得User 的favorites:

User.findOne({_id: currentUser}).exec(function(err, user){
  console.log(user);
  if (err)
    throw err;

  if(!user){
    console.log("can't find user");
  }else{ // user found
    user.populate('favorites.users');
    user.populate('favorites.places');

    // do something to the 'user.favorites' object

  }
});

虽然这不能按预期工作,但 user.favorites.users 和 user.favorites.places 都未定义。

我认为我可以像上面那样填充,但显然情况并非如此。从我读到的内容来看,我一定遗漏了一些表明(可能)ref'ed 文档的模型的东西?这个流程对我来说很新鲜,我有点迷路了。

无论如何我可以通过如上所述填充我的查询结果来获得users 和places 的数组吗?我尝试将populate 与exec 链接起来,但它也不起作用。有没有更好的方法来实现这个结果?

编辑:如果需要,在数据库中,User 文档显示为:

{
  "_id": "56c36b330fbc51ba19cc83ff",
  "name": "John Doe",
  "favorites": {
    "places": [],
    "users": [
      "56b9d9a45f1ada8e0c0dee27"
    ]
  }
}

编辑:更多细节...我目前正在像这样存储/删除参考 ObjectIds(注意 targetID 是一个字符串):

user.favorites.users.push({ _id: mongoose.Types.ObjectId(targetID)});
user.favorites.users.pull({ _id: mongoose.Types.ObjectId(targetID)});

另外,我需要用各自的文档以及填充users 和places,我认为这在我最初的问题中可能不清楚。

【问题讨论】:

  • ref 值应该是引用模型的名称,而不是架构。

标签: node.js mongodb mongoose-populate


【解决方案1】:

试试:

User
.findOne({_id: currentUser})
.populate('favorites.users')
.populate('favorites.places')
.exec( function (err, user) {
  // user.favorites.users
  // user.favorites.places
});

【讨论】:

  • 也许我解释得不够充分:这行得通,但我需要用各自的文档填充 users 和 places 数组。你能指出缺少什么吗?
  • 基本上,我在user.favorites.users 对象中看到的只是其他用户 的ID 字符串...
【解决方案2】:

嗯,我通过适当关注文档(以及 @DJeanCar 的 (+1'd) 帮助/指针)找到了我需要的东西。

Mongoose 的docs 关于跨多个级别填充,我已经达到了这个解决方案:

User.findOne({_id: currentUser})
    .populate({path:"favorites.users", populate: "name"})
    .populate({path:"favorites.places", populate: "name"})
    .exec(function(err, user){
      if(err)
        throw err;

      if(!user){
        console.log("couldnt find source user");
      }else{
        // here, user.favorites is populated and I can do what I need with the data
      }
    });

另外,据我所知,如果您需要在填充后过滤所需的文档字段,您还可以在populate() 的选项中传递select: "field field field"。

希望这对有类似问题的人有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 2019-09-13
    • 2017-06-02
    • 1970-01-01
    • 2018-06-20
    • 2013-01-25
    • 2015-08-08
    相关资源
    最近更新 更多