I need to combine results from two different documents in Mongo. I have a function like this:
async function getReviewsByUserId (req, res) {
const { userId } = req.params
const reviews = await Review.find({ userId }).lean() || []
return res.status(200).send(reviews.reverse())
}
The reviews array looks like this:
{
"_id" : ObjectId("1263b55ef2cdd3ebb0654d1dd"),
"launchId" : "7fb83b40-7c6f-4099-aaed-fe9d0dc03111",
"userId" : "1",
}
{
"_id" : ObjectId("6355565cf5ef2cddebb065584"),
"launchId" : "12b53940-136f-3399-aaed-fe9d0dc05473",
"userId" : "7fb83b40-7c6f-4099-aaed-fe9d0dc03112",
}
I need to use the launchId from each review, look up a launch object from my mongo database, and combine that with the correct object in the reviews array.
Example of what I mean:
async function getReviewsByUserId (req, res) {
const { userId } = req.params
const reviews = await Review.find({ userId }).lean() || []
const launches = await Launch.find(/* find all launches where launch._id is equal to reviews.launchId*/)
return res.status(200).send(launches.reverse())
}
So if launches data looks like this (and launches is also an array of ALL launches):
{
"_id" : "12b53940-136f-3399-aaed-fe9d0dc05473",
"name" : "The Park",
}
Then how can I merge this with the reviews payload where the launch._id == reviews.launchId so that the final data looks like this:
{
"_id" : ObjectId("1263b55ef2cdd3ebb0654d1dd"),
"launchId" : "7fb83b40-7c6f-4099-aaed-fe9d0dc03111",
"userId" : "1",
}
{
"_id" : ObjectId("6355565cf5ef2cddebb065584"),
"launchId" : "12b53940-136f-3399-aaed-fe9d0dc05473",
"userId" : "7fb83b40-7c6f-4099-aaed-fe9d0dc03112",
"launch": {
"_id" : "12b53940-136f-3399-aaed-fe9d0dc05473",
"name" : "The Park",
}
}
>Solution :
This could be achieved by using aggregate pipelines.
- Filter
reviewsbyuserIdin$matchstage $lookupforlaunches$unwindthelauncharray to an object
The solution could be:
async function getReviewsByUserId(req, res) {
const { userId } = req.params;
const launches = await Review.aggregate([
{
$match: {
userId
}
},
{
$lookup: {
from: "launches",
localField: "launchId",
foreignField: "_id",
as: "launch"
}
},
{
$unwind: {
path: "$launch",
preserveNullAndEmptyArrays: true
}
}
]);
return res.status(200).send(launches.reverse());
}