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.