Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose populate within an object?

I'm not sure how to populate the sample schema below or if it is even possible. Can a reference be within an object like below? If you can, how would you populate it? E.g. .populate('map_data.location');?

var sampleSchema = new Schema({
  name: String,
  map_data: [{
    location: {type: Schema.Types.ObjectId, ref: 'location'},
    count: Number
  }]
});

Or will I have to have two separate arrays for location and count like so:

// Locations and counts should act as one object. They should
// Be synced together perfectly.  E.g. locations[i] correlates to counts[i]
locations: [{ type: Schema.Types.ObjectId, ref: 'location'}],
counts: [Number]

I feel like the first solution would be the best, but I'm not entirely sure how to get it working within Mongoose.

Thank you very much for any help!

like image 468
Ryan Endacott Avatar asked Jan 30 '13 00:01

Ryan Endacott


People also ask

How does populate work in Mongoose?

Mongoose Populate() Method. In MongoDB, Population is the process of replacing the specified path in the document of one collection with the actual document from the other collection.

How do you populate an array of objects?

In an array of objects, we have to initialize each element of array i.e. each object/object reference needs to be initialized. Different ways to initialize the array of objects: By using the constructors. By using a separate member method.


3 Answers

The first solution is possible.

Mongoose currently has limitations (see this ticket here) populating multiple levels of embedded documents, however is very good at understanding nested paths within a single document - what you're after in this case.

Example syntax would be:

YourSchema.find().populate('map_data.location').exec(...)

Other features, such as specifying getters / setters on paths, orderBy and where clauses, etc. also accept a nested paths, like this example from the docs:

personSchema.virtual('name.full').get(function () {   return this.name.first + ' ' + this.name.last; }); 

Internally Mongoose splits the string at the dots and sorts everything out for you.

like image 186
Jed Watson Avatar answered Sep 28 '22 10:09

Jed Watson


First option is ok, but if someone would have problems with that query map_data.location - Mongoose returns empty array instead of object - I found that this will work:

.populate({
     path: 'map_data.location',
     model: 'Location'
})
like image 31
kkochanski Avatar answered Sep 28 '22 09:09

kkochanski


   YourSchema.find()
       .populate({
            path: 'map_data',
            populate: {
                path: 'location' 
            }
    }).exec(...)

The above statement will populate array of map_data and also the location object of each map_data.

hope this helps someone.

like image 26
Otis-iDev Avatar answered Sep 28 '22 10:09

Otis-iDev