Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose populate embedded

I use Mongoose.js and cannot solve problem with 3 level hierarchy document.

There 2 ways to do it.

First - without refs.

C = new Schema({     'title': String, });  B = new Schema({     'title': String,     'c': [C] });  A = new Schema({     'title': String,     'b': [B] }); 

I need to show C record. How can i populate / find it, knowing only _id of C?

I was try use:

A.findOne({'b.c._id': req.params.c_id}, function(err, a){     console.log(a); }); 

But i dont know how to get from returnet a object only c object that i need.

Second if working with refs:

C = new Schema({     'title': String, });  B = new Schema({     'title': String,     'c': [{ type: Schema.Types.ObjectId, ref: 'C' }] });  A = new Schema({     'title': String,     'b': [{ type: Schema.Types.ObjectId, ref: 'B' }] }); 

How to populate all B, C records to get hierarchy?

I was try to use something like this:

A .find({}) .populate('b') .populate('b.c') .exec(function(err, a){     a.forEach(function(single_a){         console.log('- ' + single_a.title);         single_a.b.forEach(function(single_b){             console.log('-- ' + single_b.title);             single_b.c.forEach(function(single_c){                 console.log('--- ' + single_c.title);             });         });     }); }); 

But it will return undefined for single_c.title. I there way to populate it?

Thanks.

like image 410
Oleg2tor Avatar asked Oct 25 '12 21:10

Oleg2tor


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 does Mongoose populate work under the hood?

Mongoose uses two queries to fulfill the request. The a collection is queried to get the docs that match the main query, and then the j collection is queried to populate the d field in the docs.

Does Mongoose populate use lookup?

Mongoose's populate() method does not use MongoDB's $lookup behind the scenes. It simply makes another query to the database. Mongoose does not have functionalities that MongoDB does not have.


1 Answers

As of Mongoose 3.6 the ability to recursively populate related documents in a query has been added. Here is an example of how you might do it:

 UserList.findById(listId)          .populate('refUserListItems')          .exec(function(err, doc){              UserListItem.populate(doc.refUserListItems, {path:'refSuggestion'},                    function(err, data){                         console.log("User List data: %j", doc);                         cb(null, doc);                    }              );                });            

In this case, I am populating an array of id's in 'refUserListItems' with their referenced documents. The result of the query then gets passed into another populate query that references the field of the original populated document that I want to also populate - 'refSuggestion'.

Note the second (internal) populate - this is where the magic happens. You can continue to nest these populates and tack on more and more documents until you have built your graph the way you need it.

It takes a little time to digest how this is working, but if you work through it, it makes sense.

like image 128
BoxerBucks Avatar answered Sep 30 '22 02:09

BoxerBucks