猫鼬嵌套参考种群

Mongoose nested reference population

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

我的架构类似于以下内容(删除了不相关的属性):

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

现在我正在尝试像这样获得 Userfavorites

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.usersuser.favorites.places 都未定义。

我以为我可以像上面那样填充,但显然不是这样。从我读到的内容来看,我一定是遗漏了一些东西,表明(也许)ref'ed 文件的模型?这个流程对我来说很新,我有点迷路了。

无论如何,我可以通过填充我的查询结果来获得 usersplaces 的数组吗?我试过 populateexec 链接,但它也不起作用。有没有更好的方法来实现这个结果?

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

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

编辑:更多细节...我目前 storing/removing 像这样的参考 ObjectId(注意 targetID 是一个字符串):

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

此外,我需要用各自的文档 填充 usersplaces,我认为这在我原来的问题中可能不清楚.

尝试:

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

好吧,我通过适当关注文档(以及 @DJeanCar 的 (+1'd) help/pointers)找到了我需要的东西。

根据 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"

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