I have the following aggregate code which looks up all users in a particular category and gets their user details:
const category: any = await this.categoryModel.aggregate([
{ $match: { _id: categoryID } },
{
$lookup: {
from: "users",
localField: "_id",
foreignField: "category",
as: "users",
},
},
{
$lookup: {
from: "user_details",
localField: "users._id",
foreignField: "user",
as: "user_details",
},
},
]);
However it is being returned as two arrays in the category, one for users and one for user details. How can I project it out so the user_details is an array within each corresponding user?
Currently it outputs like this:
{
name: "category 1"
users: [{_id: "1"},{_id: "2"},{_id: "3"}]
user_details: [{user: "1", name:"Henry", age:30}, {user: "2", name:"Carol", age:60}, {user: "3", name:"Ben", age:45}]
},
However, i would like it to look like this:
{
name: "category 1"
users: [
{_id: "1", user_details: {user: "1", name:"Henry", age:30}
{_id: "2", user_details: {user: "2", name:"Carol", age:60}
{_id: "3", user_details: {user: "3", name:"Ben", age:45}
]
},
Input documents see below:
category: {_id: "cat1", name: "category 1"}
users: {_id: "1", category: "cat1"}
user_details: {_id: "ud1", user: "1", name:"Henry", age:30}
One way of doing this is using nested lookups, like this:
db.category.aggregate([
{
$match: {
_id: "cat1"
}
},
{
$lookup: {
from: "users",
let: {
categoryId: "$_id",
},
pipeline: [
{
"$match": {
$expr: {
"$eq": [
"$category",
"$$categoryId"
]
}
}
},
{
"$project": {
category: 0
}
},
{
$lookup: {
from: "user_details",
localField: "_id",
foreignField: "user",
as: "user_details",
},
}
],
as: "users"
},
},
])