I have Category
model:
Category:
...
articles: [{type:ObjectId, ref:\'Article\'}]
Article model contains ref to
Populating across multiple levels
Say you have a user schema which keeps track of the user's friends.
var userSchema = new Schema({
name: String,
friends: [{ type: ObjectId, ref: 'User' }]
});
Populate lets you get a list of a user's friends, but what if you also wanted a user's friends of friends? Specify the populate option to tell mongoose to populate the friends array of all the user's friends:
User.findOne({ name: 'Val' }).populate({
path: 'friends',
// Get friends of friends - populate the 'friends' array for every friend
populate: { path: 'friends' }
});
Reference: http://mongoosejs.com/docs/populate.html#deep-populate
Mongoose has now a new method Model.populate
for deep associations:
https://github.com/Automattic/mongoose/issues/1377#issuecomment-15911192
It might be a bit too late, but I wrote a Mongoose plugin to perform deep population at any arbitrary nested levels. With this plugin registered, you can populate category's articles and accounts with just a single line:
Category.deepPopulate(categories, 'articles.account', cb)
You can also specify populate options to control things like limit
, select
... for each populated path. Checkout the plugin documentation for more information.
Easiest way to accomplish this in 3.6 is to use Model.populate
.
User.findById(user.id).select('-salt -hashedPassword').populate('favorites.things').exec(function(err, user){
if ( err ) return res.json(400, err);
Thing.populate(user.favorites.things, {
path: 'creator'
, select: '-salt -hashedPassword'
}, function(err, things){
if ( err ) return res.json(400, err);
user.favorites.things = things;
res.send(user.favorites);
});
});
globals.models.Category.find()
.where('issue', req.params.id)
.sort('order')
.populate('articles')
.exec(function(err, categories) {
globals.models.Account.populate(categories, 'articles.account', function(err, deepResults){
// deepResult is populated with all three relations
console.log(deepResults[0].articles[0].account);
});
});
The following example is inspired by the question asked @codephobia and populates two levels of many relationships. First fetch a user
, populate its array of related order
s and include each orderDetail
.
user.model.findOne()
.where('email', '***@****.com')
.populate('orders')
.exec(function(err, user) {
orderDetail.model.populate(user, 'orders.orderDetails', function(err, results){
// results -> user.orders[].orderDetails[]
});
});
This works fine in 3.8.8
but should work in 3.6.x
.
This concept is deep Population. Here Calendar,Subscription,User,Apartment are mongoose ODM models in different levels
Calendar.find({}).populate({
path: 'subscription_id',model: 'Subscription',
populate: {path: 'user_id',model: 'User',
populate: {path: 'apartment_id',model: 'Apartment',
populate: {path: 'caterer_nonveg_id',
model: 'Caterer'}}}}).exec(function(err,data){
if(!err){
console.log('data all',data)
}
else{
console.log('err err err',err)
}
});