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?
To populate nested array in Mongoose, we can use the populate method. Project. find(query) . populate({ path: 'pages', populate: { path: 'components', model: 'Component' } }) .
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.
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.
Mongoose 4 support this
Car .find() .populate({ path: 'partIds', model: 'Part', populate: { path: 'otherIds', model: 'Other' } })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With