wscourge wscourge - 1 year ago 157
Node.js Question

Mongoose multiple deep populates

Say, I have

Manager
schema:

{
name: { type: String },
clients: [{ type: Mongoose.Schema.ObjectId, ref: 'Client'}]
}


And, I have
Client
schema:

{
name : { type String },
cars : [{ type: Mongoose.Schema.ObjectId, ref: 'Car' }],
houses: [{ type: Mongoose.Schema.ObjectId, ref: 'House' }]
}


And
Car
and
House
as well (their structure is not important for the matter. How do I deep populate multiple
Client
's fields in the single
.populate()
call?

What have I tried:

Manager.find()
.populate({
path: 'users',
populate: { path: 'cars' },
populate: { path: 'houses' }
});


and it would truly surprise me if it worked (as I overwrite previously declared
populate
key passed to the
.populate()
method). My example obviously returns populated
houses
field per user - the one which comes last. Honestly, no idea, nothing in the docs either. Is it even supported? I know it is for 'shallow' populate, based on my example:

User.populate('cars')
.populate('houses')


What about the deep one?

Answer Source

1) Pass an array of objects with properties to be populated:

Manager.find()
    .populate({
         path    : 'users',
         populate: [
             { path: 'cars' },
             { path: 'houses' }
         ]
    });

This solution enables to use deep populate to its full extent. Consider:

Manager.find()
    .populate({
         path    : 'users',
         populate: [
             { path: 'cars' },
             { 
                path    : 'houses',
                populate: {
                    path    : 'rooms',
                    populate: 'windows'
                }
             }
         ]
    });

2) Pass string of space-delimited collections to be populated:

Manager.find()
    .populate({
         path    : 'users',
         populate: 'cars houses'
    });
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download