Mongoose populate embedded

javascript, mongodb, mongoose, node.js, nosql

Solution

In Mongoose 4 you can populate documents across multiple levels:

Say you have a User schema which keeps track of the user's friends.

var userSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});

Firstly `populate()` lets you get a list of user friends. But what if you also wanted a user's friends of friends? In that case, you can specify a `populate` option to tell mongoose to populate the `friends` array of all the user's friends:

User.
  findOne({ name: 'Val' }).
  populate({
    path: 'friends',
    // Get friends of friends - populate the 'friends' array for every friend
    populate: { path: 'friends' }
  });

Taken from: http://mongoosejs.com/docs/populate.html#deep-populate

Problem

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.

Original source

Related problems