Mongoose nested reference population

微笑、不失礼 提交于 2019-12-12 01:52:59

问题


I'm having trouble understanding some of the concepts behind mongoose's populate methods. I had an embedded approach working first, although, as I feared a big overhead of data and out-of-sync documents going around I tried changing the paradigm to ref other documents.

My Schema is similar to the following (removed irrelevant properties):

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

Now I'm trying to get a User's favorites like this:

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

  }
});

Although this doesn't work as intended, as both user.favorites.users and user.favorites.places come up undefined.

I thought that I could populate as above, but apparently, that's not the case. From what I read, I must be missing something indicating (maybe) the model of the ref'ed document? This flow is very new to me and I'm kinda lost.

Is there anyway I can get an array of users and places by populating my query result as above? I tried populate chained with exec and it doesn't work either. Is there a better way to achieve this result?

EDIT: In case it's needed, in the DB, a User document shows up as:

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

EDIT: A couple more details... I'm currently storing/removing the reference ObjectIds like this (note targetID is a String):

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

Also, I need to populate the users and places with their respective documents aswell, I think that might not be clear in my original question.


回答1:


Try:

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



回答2:


Well, I figured out what I needed by paying proper attention to the docs (and also with @DJeanCar 's (+1'd) help/pointers).

By Mongoose's docs regarding Populating across multiple levels, I've reached this solution:

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

Also, from what I could tell, you can also pass select: "field field field" in populate()'s options, should you need to filter the document fields you require after population.

Hope this helps someone with similar issues!



来源:https://stackoverflow.com/questions/36042284/mongoose-nested-reference-population

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!