65
votes

In Mongoose, I can use a query populate to populate additional fields after a query. I can also populate multiple paths, such as

Person.find({})
 .populate('books movie', 'title pages director')
 .exec()

However, this would generate a lookup on book gathering the fields for title, pages and director - and also a lookup on movie gathering the fields for title, pages and director as well. What I want is to get title and pages from books only, and director from movie. I could do something like this:

Person.find({})
 .populate('books', 'title pages')
 .populate('movie', 'director')
 .exec()

which gives me the expected result and queries.

But is there any way to have the behavior of the second snippet using a similar "single line" syntax like the first snippet? The reason for that, is that I want to programmatically determine the arguments for the populate function and feed it in. I cannot do that for multiple populate calls.

4

4 Answers

9
votes

you can also do something like below:

{path:'user',select:['key1','key2']}
144
votes

After looking into the sourcecode of mongoose, I solved this with:

var populateQuery = [{path:'books', select:'title pages'}, {path:'movie', select:'director'}];

Person.find({})
 .populate(populateQuery)
 .execPopulate()
2
votes

This is how it's done based on the Mongoose JS documentation http://mongoosejs.com/docs/populate.html

Let's say you have a BookCollection schema which contains users and books In order to perform a query and get all the BookCollections with its related users and books you would do this

models.BookCollection
    .find({})
    .populate('user')
    .populate('books')
    .lean()
    .exec(function (err, bookcollection) {
    if (err) return console.error(err);
    try {
        mongoose.connection.close();
        res.render('viewbookcollection', { content: bookcollection});

    } catch (e) {
        console.log("errror getting bookcollection"+e);
    }
2
votes

You achieve that by simply passing object or array of objects to populate() method.

const query = [
    {
        path:'books', 
        select:'title pages'
    }, 
    {
        path:'movie', 
        select:'director'
    }
];
const result = await Person.find().populate(query).lean();

Consider that lean() method is optional, it just returns raw json rather than mongoose object and makes code execution a little bit faster! Don't forget to make your function (callback) async!