By default, Mongoose only supports populating nested models at one level of depth. This plugin makes it very simple to populate nested models at any level of depth.
npm install mongoose-deep-populate
Sample usages are based on the following schemas:
var UserSchema = new Schema({})
var CommentSchema = new Schema({
user : {type: Number, ref: 'User'}
})
var PostSchema = new Schema({
user : {type: Number, ref: 'User'},
comments: [{type: Number, ref: 'Comment'}],
likes : [{user: {type: Number, ref: 'User'}}],
approved: {status: Boolean, user: {type: Number, ref: 'User'}}
})
var deepPopulate = require('mongoose-deep-populate');
PostSchema.plugin(deepPopulate, options /* more on options below */);
On Post
model:
Post.deepPopulate(posts, 'comments.user', function (err, _posts) {
// _posts is the same instance as posts and provided for convenience
posts.forEach(function (post) {
// post.comments and post.comments.user are fully populated
});
});
On an instance of Post
:
post.deepPopulate('comments.user', function (err, _post) {
// _post is the same instance as post and provided for convenience
});
On Query
:
Post.find().deepPopulate('comments.user').exec(function (err, posts) { ... });
Post.findOne().deepPopulate('comments.user').exec(function (err, post) { ... });
Post.findById(id).deepPopulate('comments.user').exec(function (err, post) { ... });
Pass paths in a space- or comma-delimited string:
post.deepPopulate('user comments.user likes.user approved.user', cb);
Or use an array of strings:
post.deepPopulate(['comments.user', 'user', 'likes.user', 'approved.user'], cb);
Specify whitelist
option to ensure only certain paths can be populated. This is to prevent potential performance and security issues if you allow API clients to supply population paths.
PostSchema.plugin(deepPopulate, {
whitelist: [
'user',
'comments.user'
]
});
Use the populate
option to supply paths with corresponding Mongoose populate options.
PostSchema.plugin(deepPopulate, {
populate: {
'comments.user': {
select: 'name',
options: {
limit: 5
}
},
'approved.user': {
select: 'name'
}
}
});
Use rewrite
option to rewrite provided paths as well as paths in whitelist
and populate
. This is useful when you allow API clients to supply population paths (e.g. via query string) and want to make these paths more user-friendly. For example:
PostSchema.plugin(deepPopulate, {
rewrite: {
author: 'user',
approver: 'approved.user'
}
});
// assume the query string is: ?populate=author,approver
post.deepPopulate(req.query.populate, cb);
Finally, you can override the above plugin options when invoking deepPopulate
.
Post.deepPopulate(posts, paths, {
whitelist: [],
populate: {},
rewrite: {}
}, cb)
post.deepPopulate(paths, {
whitelist: [],
populate: {},
rewrite: {}
}, cb);
Post.find({}).deepPopulate(paths, {
whitelist: [],
populate: {},
rewrite: {}
}).exec(cb)
The test suite will drop the database each run, so only run it against a test database. To run tests, execute this command where --db
is the connection string.
gulp test --db mongodb://127.0.0.1/mongoose_deep_populate_test_db
- [Bug] Apply
lean
to populated documents
- [Feature] Apply
rewrites
towhitelist
andpopulate
- [Feature] Add
deepPopulate
toQuery
- [Feature] Support space delimiter in paths
- [Feature] Support populate options
- [Feature] Override options per call
- [Bug] Handle null paths and callback
- Initial release
MIT