Dan
Dan

Reputation: 41

Mongoose nested/deep populate

I know this question has been asked a lot of times but I'm kind of new to mongodb/mongoose! Currently I am working on a MEAN stack for a medical software. The following is my schema:

var usersSchema = new Schema({
    _id      : {type : mongoose.Schema.ObjectId}
  //...
});
mongoose.model('Users', usersSchema);

var doctorsSchema = new Schema({
    _id      : {type : mongoose.Schema.ObjectId},
    userid      : {type : mongoose.Schema.ObjectId, ref : 'Users' },
  //...
});
mongoose.model('Doctors', doctorsSchema);

var appointmentsSchema = new Schema({
  _id      : {type : mongoose.Schema.ObjectId},
  doctorids       : [ {type : mongoose.Schema.ObjectId, ref : 'Doctors'} ]
  //...
});
mongoose.model('Appointments', appointmentsSchema);

Nested Mongoose Populate: How do I implement a nested mongoose populate on Appointments.find() in a way that Appointments.find().populate('doctorids') should populate the array of Doctors and the array of Doctors in turn should populate the Users each Doctor points to. As per https://github.com/LearnBoost/mongoose/wiki/3.6-Release-Notes#population they added Model.Populate! So I tried this but its NOT populating the Users inside the doctorids

 

Appointments
  .find({})
  .populate('doctorids')  // This is working
  .exec(function (err, doc) {
    if (err) {
      handleError(err);
      return;
    }
    Doctors //**Shouldn't this populate the doctors Users inside Doctors?**
      .populate(doc, {path: 'doctorids.userid'}, function(err, doc) {       
    }); 
    res.json({
      appointments: doc //Appointsments.Doctorids[].Userid is NOT populated
    });
});  

[Edited: Moved the other questions to a new post @ https://stackoverflow.com/questions/27412928/mongoose-nested-populate-sort-search-referenced-attributes ]

Upvotes: 2

Views: 3428

Answers (1)

Buu
Buu

Reputation: 50335

There are many questions, I'm going to address only the deep population portion (the first question). (Also, I recommend you to split the question to multiple ones in case people have the answer to one but not all.)

While Mongoose supports nested population, you have to manually invoke populate on each model to be populated at every nested level. Alternative, you can use the mongoose-deep-populate plugin to do this (disclaimer: I'm the author of that plugin). For example, you can write this to populate doctors and users:

Apartments.find({}, function (err, apts) {
  Apartments.deepPopulate(docs, 'doctorids.userid', function (err, apts) {
    // now every `apt` instance has doctors and user
  })
})

You can also specify Mongoose populate options to control sort order for each populated path, like this:

var options = {
  doctorids: {
    options: {
      sort: '-name'
    }
  }
}
Apartments.deepPopulate(docs, 'doctorids.userid', options, cb)

Check out the plugin documentation for more information.

Upvotes: 3

Related Questions