MongoDB聚合使用$sum搭配多个$cond计算积分结果恒为20问题
问题排查结论
MongoDB聚合操作完全支持$sum搭配多个$cond表达式实现按条件累加积分的逻辑,你遇到的固定返回20的问题和语法合法性无关,是条件判断的写法不符合BSON比较规则导致的。
根因说明
- 你的测试文档中
matches数组的每个元素都是空数组[],原代码中{ $gt: [{ $arrayElemAt: ["$matches", 0] }, 0] }的逻辑是直接将空数组和数值0做大小比较。 - 根据MongoDB的BSON类型比较规则,Array类型的比较优先级高于所有数值类型,任何数组和数值做大小比较时,数组都会被判定为更大的值,空数组也不例外。
- 因此原代码中两个
$and包裹的所有判断条件永远返回true,两个$cond分支都会返回10,经$sum累加后固定得到20,完全没有触发你预期的「判断数组元素长度」逻辑。
修正方案
你需要先通过$size取出matches对应位置子数组的长度,再和0做大小比较,不能直接拿子数组本身和数值对比。修正后的聚合阶段代码如下:
{ $project: { points: { $sum: [ { $cond: [ { $and: [ { $gt: [{ $size: { $arrayElemAt: ["$matches", 0] } }, 0] }, { $gt: [{ $size: { $arrayElemAt: ["$matches", 1] } }, 0] }, { $gt: [{ $size: { $arrayElemAt: ["$matches", 2] } }, 0] } ] }, 10, 0 ] }, { $cond: [ { $and: [ { $gt: [{ $size: { $arrayElemAt: ["$matches", 3] } }, 0] }, { $gt: [{ $size: { $arrayElemAt: ["$matches", 4] } }, 0] }, { $gt: [{ $size: { $arrayElemAt: ["$matches", 5] } }, 0] } ] }, 10, 0 ] } ] } } }
使用你提供的测试文档运行上述修正代码,所有子数组长度均为0,两个$cond都返回0,最终points值为0,符合预期。
内容的提问来源于stack exchange,提问作者SaroVin
相关产品推荐
相关产品推荐

