Mongoose: deep population (populate a populated field)
I have Category
model:
Category:
...
articles: [{type:ObjectId, ref:'Article'}]
Article model contains ref to Account model
.
Article:
...
account: {type:ObjectId, ref:'Account'}
So, with populated articles
Category model will be:
{ //category
articles: //this field is populated
[ { account: 52386c14fbb3e9ef28000001, // I want this field to be populated
date: Fri Sep 20 2013 00:00:00 GMT+0400 (MSK),
title: 'Article 1' } ],
title: 'Category 1' }
The questions is: how to populate subfield (account) of a populated field ([articles])? Here is how I do it now:
globals.models.Category
.find
issue : req.params.id
null
sort:
order: 1
.populate("articles") # this populates only article field, article.account is not populated
.exec (err, categories) ->
console.log categories
I know it was discussed here: Mongoose: Populate a populated field but no real solution was found
Solution 1:
Firstly, update mongoose 3 to 4 & then use the simplest way for deep population in mongoose as below :
Suppose you have Blog schema having userId as ref Id & then in User you have some review as ref Id for schema Review. So Basically, you have three schema : 1. Blog 2. User 3. Review
And, you have to query from blog, which user owns this blog & the user review. So you can query your result as :
BlogModel
.find({})
.populate({
path : 'userId',
populate : {
path : 'reviewId'
}
})
.exec(function (err, res) {
})
Solution 2:
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
Solution 3:
Mongoose has now a new method Model.populate
for deep associations:
https://github.com/Automattic/mongoose/issues/1377#issuecomment-15911192
Solution 4:
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.