Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose populate nested array

Tags:

Assuming the following 3 models:

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

When I query for Cars I can populate the parts:

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

Is there a way in mongoose to populate the otherIds in the nested parts objects for all the cars.

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

I can probably iterate over each car and try to populate:

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

Problem there is that I have to use a lib like async to make the populate call for each and wait until all are done and then return.

Possible to do without looping over all cars?

like image 470
lostintranslation Avatar asked Jan 27 '15 20:01

lostintranslation


People also ask

Can we populate array Mongoose?

To populate nested array in Mongoose, we can use the populate method. Project. find(query) . populate({ path: 'pages', populate: { path: 'components', model: 'Component' } }) .

How does populate work in Mongoose?

Mongoose Populate() Method. In MongoDB, Population is the process of replacing the specified path in the document of one collection with the actual document from the other collection.


2 Answers

Update: Please see Trinh Hoang Nhu's answer for a more compact version that was added in Mongoose 4. Summarized below:

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

Mongoose 3 and below:

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

For nested populations like this, you have to tell mongoose the Schema you want to populate from.

like image 157
Svenskunganka Avatar answered Sep 19 '22 04:09

Svenskunganka


Mongoose 4 support this

Car .find() .populate({   path: 'partIds',   model: 'Part',   populate: {     path: 'otherIds',     model: 'Other'   } }) 
like image 26
James Avatar answered Sep 23 '22 04:09

James