I'm trying to lookup every rentalContractId from rentalcontractdetails table. The product document looks something like this:
{
"productPrice": [
{
"rentalContractId": ObjectId("64018dfc8a7d37f378d6c427"),
"price": 20
},
{
"rentalContractId": ObjectId("64018dfc8a7d37f378d6c426"),
"price": 10
}
]
}
I just need to lookup rentalContractId. So was doing the below query in aggregation to get that output,
db.products.aggregate([
{
$lookup: {
from: "rentalcontractdetails",
localField: "productPrice.rentalContractId",
foreignField: "_id",
as: "rentalContract",
},
}, { $set: {
"productPrice.rentalContract": "$rentalContract"
}}])
but this is producing output like this. "productPrice":
[
{
"rentalContractId": "64018dfc8a7d37f378d6c427",
"price": 20,
"rentalContract": [
{
"_id": "64018dfc8a7d37f378d6c427",
"contractType": "8 - Days Rental",
"contractDaysInNumber": 8,
"createdAt": "2023-03-03T06:04:44.531Z",
"isDeleted": false,
"isArchived": false
},
{
"_id": "64018dfc8a7d37f378d6c426",
"contractType": "4 - Days Rental",
"contractDaysInNumber": 4,
"createdAt": "2023-03-03T06:04:44.531Z",
"isDeleted": false,
"isArchived": false
}
]
},
{
"rentalContractId": "64018dfc8a7d37f378d6c426",
"price": 10,
"rentalContract": [
{
"_id": "64018dfc8a7d37f378d6c427",
"contractType": "8 - Days Rental",
"contractDaysInNumber": 8,
"createdAt": "2023-03-03T06:04:44.531Z",
"isDeleted": false,
"isArchived": false
},
{
"_id": "64018dfc8a7d37f378d6c426",
"contractType": "4 - Days Rental",
"contractDaysInNumber": 4,
"createdAt": "2023-03-03T06:04:44.531Z",
"isDeleted": false,
"isArchived": false
}
]
}
]
expected output:
{
"productPrice": [
{
"rentalContractId": {
"_id": "64018dfc8a7d37f378d6c427",
"contractType": "8 - Days Rental",
},
"price": 20
},
{
"rentalContractId": {
"_id": "64018dfc8a7d37f378d6c426",
"contractType": "4 - Days Rental",
}
"price": 10
}
]
}
Thanks in advance.
One option is to use $lookup
with pipeline, and update your $set
step to use $mergeObjects
inside $map
:
db.products.aggregate([
{$lookup: {
from: "rentalcontractdetails",
localField: "productPrice.rentalContractId",
foreignField: "_id",
as: "rentalContract",
pipeline: [{$project: {contractType: 1}}]
}},
{$project: {
_id: 0,
productPrice: {$map: {
input: "$rentalContract",
in: {$mergeObjects: [
{rentalContractId: "$$this"},
{price: {$arrayElemAt: [
"$productPrice.price",
{$indexOfArray: ["$productPrice.rentalContractId", "$$this._id"]}
]}}
]}
}}
}}
])
See how it works on the playground example
$lookup
and mongoose populate
are two different things, working with two different mechanisms. The original question was mixing the two, but used $lookup
in the code, so I guess this was the intention.