Search code examples
mongoosemongoose-populate

How many database queries executing when using populate?


Have following scenario -

   const Person = mongoose.model('Person', {
        name: String
    });
    const FamilyTree = mongoose.model('FamilyTree', {
        person: { type: Schema.Types.ObjectId, ref: 'Person' },
        children: [FamilyTree]
    });


    const run = async => {
        await Promise.all(['Bob', 'Mike', 'Rory'].map( name => Person.create({name}) ));

        let bob = await Person.find({name: 'Bob'}); // [request to BD] total requests = 1
        let mike = await Person.find({name: 'Mike'}); // [request to BD] total requests = 2
        let rory = await Person.find({name: 'Rory'}); // [request to BD] total requests = 3

        await FamilyTree.create({
            person: bob._id,
            children: [
                {
                    person: mike._id,
                    children: [
                        {
                            person: rory._id,
                            children: []
                        }
                    ]
                }
            ]
        });

        await FamilyTree.find().populate('person').exec(); // how many db requests will there be? 1 or 3?
    }

How many database queries executing when using populate, provided that the response contains the following data?

Data extracted from database -

{
    person: {name: 'Bob'},
    children: [{person: 'Mike', children: [{name: 'Rory', children: []}]}]
}

Solution

  • Great Question, I was curious too. then I found this.

    Mongoose does some smart stuff behind the scenes. If you look at the actual query being made as a result of this populate query, it’ll look something like this under the hood

    FamilyTree.find({});
    person.find({ _id: { $in: ['5678', '9012', '3456'] } });
    

    So its just an $in query! Mongoose collects all of the _id fields that it needs to look for per collection, and then after that… I’m not quite sure. Looking at the source code, it looks like it does some smart stuff to reflect on the results of that query and map the correct objects back to each original document, based on its position in the populate graph that you passed into the query… or something like that (you can look over the source code starting around line 2468 of lib/model.js if you’re so inclined).

    Reference: http://frontendcollisionblog.com/mongodb/2016/01/24/mongoose-populate.html