How to populate lookup result in mongodb?

Help Post
How do I populate How to populate lookup result in mongodb?

Scenario:
I have a Comment Model, parts of it looks like this:

const CommentSchema = mongoose.Schema({
    userId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'user',
    },
    contentId: {
        type: String,
    },
    repliedTo: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'comment',
    },
    text: {
        type: String,
        required: true,
    }
});

module.exports = mongoose.model('comment', CommentSchema);

Since my Comment Model is referring to my User Model, here is part of its schema:

const UserSchema = mongoose.Schema({
    name: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        trim: true,
        unique: 'Email already exists',
        match: [/.+\@.+\..+/, 'Please fill a valid email address'],
        required: 'Email is required',
    },
    photoUrl: {
        type: String,
    },  
    // this will be saved as hashed
    password: {
        type: String,
        required: 'Password is required',
    },
});
module.exports = mongoose.model('user', UserSchema);

When I make comment on a post a new comment gets added to that post, but the repliedTo field stays null. When I make a reply to a comment, it counts as a new comment but this time the repliedTo field will refer to the comment’s _id it’s replying to.

So if a comment is made on a content and that comment’s id is “60e70494c3920d001c7fa6d6” and if a comment is made as a reply to that comment, then the reply’s repliedTo field will be “60e70494c3920d001c7fa6d6”

Now for a certain content I want to find the comments that were made on it and replies to each comment; I have to also make sure that the replies to a comment don’t show up as an independent comment. By using the MongoDB’s aggregate query’s $lookup function I am able to do so, here is my code:

let comment = await Comment.aggregate([
            [
                {
                    $match: {
                        contentId: req.params.contentId,
                    },
                },
                {
                    $lookup: {
                        from: 'comments',
                        localField: '_id',
                        foreignField: 'repliedTo',
                        as: 'replies',
                    },
                },
                {
                    $match: {
                        repliedTo: {
                            $eq: null,
                        },
                    },
                },
            ],
        ]);
    
const populateQuery = [
            {
                path: 'userId',
                select: '_id name photoUrl',
            },
            
        ];
        
comment = await Comment.populate(comment, populateQuery);

Result:

[
  {
    "_id": "60e70494c3920d001c7fa6d6",
    "text": "This is nice ",
    "contentId": "60c3eda65d90e20008cab22a",
    "userId": {
      "_id": "60b74eea3907f4001c28745c",
      "name": "Meet",
      "photoUrl": "https://images.unsplash.com/photo-1509042239860-f550ce710b93?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80"
    },
    "__v": 0,
    "replies": [
      {
        "_id": "60e705e6c3920d001c7fa6de",
        "text": "I also think this is nice ",
        "contentId": "60c3eda65d90e20008cab22a",
        "userId": "609bf455fcf4e0001c95da59",
        "repliedTo": "60e70494c3920d001c7fa6d6",
        "__v": 0
      },
      {
        "_id": "60e7066fc3920d001c7fa6e4",
        "text": "Yes you are right ",
        "contentId": "60c3eda65d90e20008cab22a",
        "userId": "60b70b79585b8b001c93cdb0",
        "repliedTo": "60e70494c3920d001c7fa6d6",
        "__v": 0
      },
      {
        "_id": "60e7069ac3920d001c7fa6ec",
        "text": "I agree with you all! ",
        "contentId": "60c3eda65d90e20008cab22a",
        "userId": "60b74eea3907f4001c28745c",
        "repliedTo": "60e70494c3920d001c7fa6d6",
        "__v": 0
      }
    ]
  },
  {
    "_id": "60e704a4c3920d001c7fa6dc",
    "text": "This is just more than nice ",
    "contentId": "60c3eda65d90e20008cab22a",
    "userId": {
      "_id": "60b74eea3907f4001c28745c",
      "name": "Meet",
      "photoUrl": "https://images.unsplash.com/photo-1509042239860-f550ce710b93?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80"
    },
    "__v": 0,
    "replies": []
  }
]

As you can see from the result that the userId in each comment gets populated with _id name and photoUrl But in my replies array the userId has just the _id.

I need to populate userId with _id name and photoUrl in the replies array of each comment

I have tried many ways but could not find a solution.
Please help me find a solution to this problem.
Thank you very much.

I found the solution.
It’s in here: node.js - How to populate lookup result in mongodb? - Stack Overflow

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.