Search code examples
mongoosemongoose-populate

Mongoose: select documents that have reference to another document


I'd like to make an Item with Comments in my MongoDB\Mongoose project. As this is my first project with MongoDB, I have a strange question:

I need an Item document like this

var itemSchema = new mongoose.Schema({
name: String
});

And I need comments for this item like this:

var commentSchema = new mongoose.Schema({
text: String,
itemId: {type: mongoose.Schema.Types.ObjectId, ref: 'Item' },
});

And I do not want to keep comment Ids in my Item document like this:

var itemSchema = new mongoose.Schema({
name: String,
comments: [ {type: mongoose.Schema.Types.ObjectId, ref: 'Comment' } ]
});

So how should I call the model Item to get all comments for this item if I know only Item.name value? Can I do it with populate() in a single mongoose request or i have to make two requests (first to get Item to lookup _id, second to get Comments where itemId == Item._id ?

Or maybe I am doing this completely wrong way?


Solution

  • You can use virtual population.

    itemSchema.virtual('comments', {
        ref: 'Comment', // The model to use
        localField: '_id', // Find comments where `localField`
        foreignField: 'itemId', // is equal to `foreignField`
    });
    

    Then if you have the document item, you would do

    item.populate('comments').execPopulate().then(() => {
        console.log(item.comments);
    });
    

    We use execPopulate() because you only want to populate comments.

    If you have the model Item, you would do

    Item.findOne(...).populate('comments').exec((err, item) => {
        console.log(item.comments);
    });