Search code examples
mongoosemongoose-schemamongoose-populate

Populate array in mongoose


How can I populate of array "ascents" help me please.

{"_id":"5d92775ab93e250910838d98",
"seminars":["5d854deecfed0e2494b03e38","5d85533e56fa1c24588824ff"],
"ascents":[
{"_id":"5d8bd237f55e4326a4faf7d0","dateAscent":"2019-09-20T00:00:00.000Z"},
{"_id":"5d8bd250f55e4326a4faf7d1","dateAscent":"2019-09-20T00:00:00.000Z"},
{"_id":"5d8bd258f55e4326a4faf7d2","dateAscent":"2019-09-20T00:00:00.000Z"},
{"_id":"5d8bd26af55e4326a4faf7d3","dateAscent":"2019-0920T00:00:00.000Z"}
],
"status":true,
"user":"5d84f154d275fd125835b4ec","__v":17
}

my model:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;


var profileSchema = new Schema({
    user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
    seminars: [{ type: Schema.Types.ObjectId, ref: 'Seminar', required: false }],
    ascents: [{ascent:{ type: Schema.Types.ObjectId, ref: 'Ascent', required: false },dateAscent:{ type: Date, required: true, default: Date.now }}],
    status: { type: Boolean, default: true }
});


module.exports = mongoose.model('Profile', profileSchema);

someone who can help me how can I do it?


Solution

  • Consider separating defining the Ascent schema so that it has its own model

    const ascentSchema = new Schema({
        dateAscent:{ 
            type: Date, 
            required: true, 
            default: Date.now 
         }
    })
    
    module.exports = mongoose.model('Ascent',ascentSchema  )
    

    Then your profile schema will look like:

    var profileSchema = new Schema({
        user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
        seminars: [{ type: Schema.Types.ObjectId, ref: 'Seminar', required: false }],
        ascents: [{type: Schema.Types.ObjectId, ref: 'Ascent'}],
        status: { type: Boolean, default: true }
    });
    
    module.exports = mongoose.model('Profile', profileSchema);
    

    To populate ascents you have to ensure you add valid _ids to the ascents array when you add to new Ascents document.

    When writing a query, in order to populate ascents array with the relevant documents you would do this:

    Profile.find().
      populate({
        path: 'ascents',
        match: { }, //you can even filter the documents in the array using this match option
        // Explicitly exclude `_id`
        select: '-_id',
        options: { limit: 5 } //Also limit the amount of documents returned
      }).
      exec();
    

    Let me know if this approach work. Just remember you have to push the _ids to the ascents array that's apart relatProfile document when you add a new Ascent document. See example from docs