#mongodb
Вопрос:
Я пытаюсь что-то рассчитать с помощью платформы агрегации mongodb. Поэтому мне нужно использовать проецируемый элемент ( который является вычисляемым полем на этапе проектирования) в другом состоянии, но я не могу получить результат.
Вот код, который я пробовал.
"$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]}
}
В этой проекции я не могу получить поле «оплата», на мой взгляд, это потому, что последнее условие не распознает «сумму в долларах».
Итак, как я могу использовать поле сумма в другом поколении полей?
Комментарии:
1.
$amount
существует только после завершения проекта, решением может быть добавление$set
этапа, просто чтобы установитьamount
вышеуказанный проект, или сохранить 1 проект и рассчитать сумму в 2 раза(второй выглядит быстрее)2. @Takis_ спасибо, два проекта решили мою проблему, если вы ответите на нее, я приму.
Ответ №1:
Новое поле, которое мы добавляем либо мы $project
/ $set
= $addFields
, существует только после завершения этапа.
2 решения, которые я предложил, были
- Добавьте один
$set
этап
{"$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]}
}}
- Сделайте каклуляцию 2 раза
{
"$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]}
}
}
Вы можете сделать это с 2 проектами также, как и вы, но 1 $set
с 1 полем, я думаю, проще.
Что касается производительности, я не знаю, как MongoDB будет их выполнять(я тестировал в прошлом и думаю, что он оптимизировал их(я тестировал несколько $map
)), например, он может быть ленивым и не вычислять $amount
, если его значение не требуется, поэтому эти 2 этапа будут выглядеть как 1 внутренне. (в этом случае 1-й будет быстрее)
Если он не ленивый, второй выглядит быстрее.