I am trying to calculate something with mongodb aggregation framework. So I need to use projected item ( which is calculated field in projection stage) in another condition, but I can't get result.
Here is the code what I tried.
"$project": {
"currency": {"$ifNull": ["$voucher_foreign_amount.symbol", "NOT ENTERED" ]},
"amount": {"$cond": [{"$not": ["$voucher_foreign_amount"]}, "$voucher_amount", "$voucher_foreign_amount.amount"]},
"voucher_type": 1,
"voucher_payment_type": 1,
"voucher_foreign_amount": 1,
"station": 1,
"paid": {"$cond": [{"$eq": ["$voucher_type", "Paid"]}, "$amount", 1]}
}
In this projection, I can't get paid field, in my opinion, it's because last condition, doesn't recognize "$amount".
So, how can I use amount field in another field generation?
CodePudding user response:
A new field that we add either we $project
/$set
=$addFields
, exists only after the stage finishes.
The 2 solutions i suggested was
- Add one
$set
stage
{"$set" : {"amount" : {"$cond": [{"$not": ["$voucher_foreign_amount"]}, "$voucher_amount", "$voucher_foreign_amount.amount"]}}},
{"$project": {
"currency": {"$ifNull": ["$voucher_foreign_amount.symbol", "NOT ENTERED" ]},
"amount" : 1,
"voucher_type": 1,
"voucher_payment_type": 1,
"voucher_foreign_amount": 1,
"station": 1,
"paid": {"$cond": [{"$eq": ["$voucher_type", "Paid"]}, "$amount", 1]}
}}
- Do the caclulation 2 times
{
"$project": {
"currency": {"$ifNull": ["$voucher_foreign_amount.symbol", "NOT ENTERED" ]},
"amount": {"$cond": [{"$not": ["$voucher_foreign_amount"]}, "$voucher_amount", "$voucher_foreign_amount.amount"]},
"voucher_type": 1,
"voucher_payment_type": 1,
"voucher_foreign_amount": 1,
"station": 1,
"paid": {"$cond": [{"$eq": ["$voucher_type", "Paid"]},
{"$cond": [{"$not": ["$voucher_foreign_amount"]}, "$voucher_amount", "$voucher_foreign_amount.amount"]},
1]}
}
}
You can do it with 2 projects also as you did, but 1 $set
with 1 field only is simpler i think.
About perfomance, i dont know how MongoDB will execute them(i tested in the past and i think it optimized it(i tested multiple $map
)), for example it might be lazy, and not calculate the $amount
unless its value is needed so those 2 stages will look as 1 internally. (in this case the 1st will be faster)
If its not lazy, the second loooks faster.