Mongoose, Deep Population on array model
Asked Answered
D

2

5

I would like to deep populate a perhaps overcomplicated model

var ParentSchema = new Schema({
  childs: [{type:Schema.ObjectId, ref: 'Child'}],
});

var ChildSchema = new Schema({
    subject: [{
        price: {type: Number},
        data: {type: Schema.ObjectId, ref: 'Subject'}
    }]
})

However, it doesn't seem to work when i use the regular population. I installed deep-populate now and use the following:

Parent.deepPopulate('childs.subjects');

I was wondering if there is perhaps an easier way to accomplish a populated array of subjects.

Dyspepsia answered 2/6, 2015 at 11:38 Comment(1)
The deepPopulate doesn't populate the data key in subject arrayDyspepsia
B
11

The mongoose-deep-populate plugin will work for this, but you need to use the right path to the deepest field you want populated. In this case, the query should look like this:

Parent.findOne().deepPopulate('childs.subject.data').exec(function(err, parents) {...});

However, it's important to realize this uses multiple queries (at least one per population level) to perform the population. First the Parent query, then the Child query, and then the Subject query. As such, it's best to embed related data when possible, but that's not practical if you need to query the child and subject data independently. So if you need your related docs in separate collections, population is the way to go.

See the section of the docs on data modeling for more info and guidance.

Boresome answered 9/6, 2015 at 12:51 Comment(0)
T
2

If you dont want to use deepPopulate plugin you can do it in 2 passes:

  1. populate child

  2. populate subject.data

    It will generate 3 requests (one for Parent, one for Child and one for Subject) as the deepPopulate plugin do:

query = Parent.findOne().populate('childs');        
query.exec(function(err, parent) {
    if (err) {
      //manage error
    };
    // now we need to populate all childs with their subject
    Child.populate(parent.childs, {
        path: 'subject.data',
        model: 'Subject'
    },function(err){
      // parent object is completely populated
    });
});
Tetrastich answered 9/6, 2015 at 19:34 Comment(1)
Thank you for your comment, It does solves my problem, however i feel more comfortable with the other solution. Thank you for your timeDyspepsia

© 2022 - 2024 — McMap. All rights reserved.