Reputation: 707
I got two collections. One contains an array of objects. These objects own a field with an id to a document in another collection. The goal is to "replace" the ref by the document. Sounds simple but I have no clue how to archive this.
E.G.
Collection "Product"
{ "_id": 1,
"alias": "ProductA"
},
{ "_id": 2,
"alias": "ProductC"
}
Collection "Order"
{ "_id": 5765,
"cart": [
{
"product": 1,
"qty": 7
}, {
"product": 2,
"qty": 6
}
]
}
What I need by a query is this:
{ "_id": 5765,
"cart": [
{
"product": {
"_id": 1,
"alias": "ProductA"
},
"qty": 7
}, {
"product": {
"_id": 2,
"alias": "ProductC"
},
"qty": 6
}
]
}
I tried a simple lookup, but the array will only contains the products. What do I need to change?
{
$lookup: {
from: "products",
let: {
tmp: "$cart.product"
},
pipeline: [
{
$match: {
$expr: {
$in: ["$_id", "$$tmp"]
}
}
}
],
as: "cart.product"
}
}
Thanks for your help.
Upvotes: 0
Views: 70
Reputation: 14287
I added a new $addFields
stage to transform the output from the $lookup
stage - it gets the desired output:
db.order.aggregate([
{
$lookup: {
from: "product",
let: {
tmp: "$cart.product"
},
pipeline: [
{
$match: {
$expr: {
$in: ["$_id", "$$tmp"]
}
}
}
],
as: "products"
}
},
{
$addFields: {
cart: {
$map: {
input: "$cart", as: "ct",
in: {
product: {
$arrayElemAt: [
{ $filter: {
input: "$products", as: "pr",
cond: {
$eq: [ "$$ct.product", "$$pr._id" ]
}
}
}, 0 ]
},
qty: "$$ct.qty"
}
}
}
}
}
] ).pretty()
Upvotes: 1