MongoDB聚合$project阶段如何引用同阶段生成的计算字段做条件判断
问题原因
MongoDB的$project阶段内所有字段的计算是并行执行的,不存在声明先后顺序的优先级,因此同阶段内无法直接引用其他新生成的计算字段,你遇到的paid字段取值异常就是这个原因导致的。
可选解决方案
方案1:拆分两个$project阶段(兼容所有MongoDB版本)
把计算amount和计算paid的逻辑拆分到两个连续的$project阶段,第二个阶段可以正常引用第一个阶段生成的amount字段。
聚合管道示例:
// 第一个$project阶段:计算amount和保留所需基础字段 { "$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 } }, // 第二个$project阶段:基于已生成的amount计算paid字段 { "$project": { "currency": 1, "amount": 1, "voucher_type": 1, "voucher_payment_type": 1, "voucher_foreign_amount": 1, "station": 1, "paid": {"$cond": [{"$eq": ["$voucher_type", "Paid"]}, "$amount", 1]} } }
方案2:使用$let内嵌变量(适用于MongoDB 4.4及以上版本,无需拆分阶段)
如果不想新增聚合阶段,可以通过$let将amount的计算逻辑封装为局部变量,在paid的计算逻辑中直接调用该变量,避免重复写计算逻辑。
示例代码:
{ "$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": { "$let": { "vars": { "calculated_amount": {"$cond": [{"$not": ["$voucher_foreign_amount"]}, "$voucher_amount", "$voucher_foreign_amount.amount"]} }, "in": {"$cond": [{"$eq": ["$voucher_type", "Paid"]}, "$$calculated_amount", 1]} } } } }
内容的提问来源于stack exchange,提问作者yigitozmen
相关产品推荐
相关产品推荐

