Joining two collections in mongodb
Your $lookup
query of users
is overwriting the comments
array. Its not working as you think it'll.
You need to unwind the comments array and then run that $lookup
of users and then group by the products.
Edit: I have updated the query with $group by code too. Also you can playa around with the query here:https://mongoplayground.net/p/2EA-Glz8Hrm
Product.aggregate([ { $match: { _id: "5cc9441feed4c258881c99cd" } }, { $lookup: { from: "comments", localField: "_id", foreignField: "product", as: "comments" } }, { $unwind: "$comments" }, { $lookup: { from: "users", localField: "comments.user", foreignField: "_id", as: "comments.user" } }, { $unwind: "$comments.user" }, { $group: { _id: "$_id", // add other fields you want to include comments: { $addToSet: "$comments" } } },])
As suggested by Hamza, I made following changes to my query
Product.aggregate([ { $match: { _id: mongoose.Types.ObjectId(id) } }, { $lookup: { from: "comments", localField: "_id", //field from input document foreignField: "product", // field from documents of the 'from' collection as: "comments" } }, { $unwind: "$comments" }, { $lookup: { from: "users", localField: "comments.user", //field from input document foreignField: "_id", // field from documents of the 'from' collection as: "comments.user" } }, { $unwind: "$comments.user" }, { $group: { _id: "$_id", title: { $first: "$title" }, // $first returns the first expression of the document it encounters, ex. first title price: { $first: "$price" }, imageUrl: { $first: "$imageUrl" }, description: { $first: "$description" }, rating: { $first: "$rating" }, comments: { $addToSet: "$comments" // group comments and create an array } } }, { $project: { _id: 1, title: 1, price: 1, imageUrl: 1, description: 1, rating: 1, comments: { _id: 1, text: 1, date: 1, user: { _id: 1, name: 1 } } } } ])
With this I got the desired result.