Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose deep populating multiple 2nd level objects not working

I have a model A wit this field :

var field = {
    foo: String,
    b: [{ type: Schema.Types.ObjectId, ref: 'B' }]
}  

and model B with this feilds :

var field = {
    c: { type: Schema.Types.ObjectId, ref: 'C' } // let's say this has 3 string field
    d: { type: Schema.Types.ObjectId, ref: 'D' } // so was this
}

Based on this answer by Trinh Hoang Nhu by doing this-

 A.find({_id:req.params.id})
    .populate({ path: 'patient', model: Patient,
        populate: {
            path: 'b',
            model: B
        },
        populate: {
            path: 'c',
            model: C
        },
    })
    .exec(function (err, doc) {
        res.send(doc);
    })

-it should return the populated 2nd level and it did but the problem is it only populate the last path declared on the .populate({}) function, in this case only the model C is populated. But when you changed it's position with model B then model B will be populated.

The query above returns something like this :

[
    {
        "foo":"Bar",
        "b": [
            {
                "c":"a32s1da4fas1a23s1da56s4c",
                "d":{
                    "foo1":"Bar1",
                    "foo2":"Bar2",
                    "foo3":"Bar3"
                }
            },
            {
                "c":"a32s1da4fas1a23s1da56s4d",
                "d":{
                    "foo1":"Bar1",
                    "foo2":"Bar2",
                    "foo3":"Bar3"
                }
            }
            // so on ...
        ]
    }
]

I was expecting something like this :

[
    {
        "foo":"Bar",
        "b": [
            {
                "c":{
                    "foo1":"Bar1",
                    "foo2":"Bar2",
                    "foo3":"Bar3"
                },
                "d":{
                    "foo1":"Bar1",
                    "foo2":"Bar2",
                    "foo3":"Bar3"
                }
            },
            {
                "c":{
                    "foo1":"Bar1",
                    "foo2":"Bar2",
                    "foo3":"Bar3"
                },
                "d":{
                    "foo1":"Bar1",
                    "foo2":"Bar2",
                    "foo3":"Bar3"
                }
            }
            // so on ...
        ]
    }
]
like image 321
CENT1PEDE Avatar asked Nov 29 '22 23:11

CENT1PEDE


1 Answers

I dont know why it even accepted multiple populate keys in the object, it is already duplicated, what you specified to populate is:

 populate: {
            path: 'b',
            model: B
        },
        populate: {
            path: 'c',
            model: C
        },

here the property populate gets duplicated, and only the last one defined is considered.

You need to specify the populate paths once as an array. So your populate property would become:

 populate: [{
            path: 'b',
            model: B
        },{
            path: 'c',
            model: C
        }]

And the query is,

A.find({_id:req.params.id})
    .populate({ path: 'patient', model: Patient,
        populate: [{
            path: 'b',
            model: B
        },{
            path: 'c',
            model: C
        }],
    })
    .exec(function (err, doc) {
        res.send(doc);
    })
like image 62
Naeem Shaikh Avatar answered Dec 06 '22 10:12

Naeem Shaikh