Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose: multiple query populate in a single call

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.

like image 511
Se7enDays Avatar asked Jan 12 '14 00:01

Se7enDays


3 Answers

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()
like image 116
Se7enDays Avatar answered Oct 20 '22 18:10

Se7enDays


you can also do something like below:

{path:'user',select:['key1','key2']}
like image 45
Kartik Garasia Avatar answered Oct 20 '22 18:10

Kartik Garasia


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!

like image 3
Rustamjon Kirgizbaev Avatar answered Oct 20 '22 20:10

Rustamjon Kirgizbaev