MongoDB中如何结合$or使用$project统计符合条件的messages数量
解决MongoDB聚合统计符合条件的数组元素数量问题
我来帮你分析问题并给出解决方案:
你的核心错误
你把$or直接作为聚合的一个阶段,这是不符合MongoDB聚合语法的——聚合管道的每个阶段必须是合法的阶段操作符(比如$match、$project、$addFields等),而$or是查询/条件操作符,不能单独作为阶段存在。
另外,你的需求是统计每个文档内符合条件的messages数组元素数量,而不是筛选文档,所以需要用$filter来过滤数组,再用$size统计长度。
正确的聚合语句
根据你的需求,我们需要对每个文档的messages数组进行过滤,留下满足(one=1 且 sender≠1) 或 (two=1 且 sender≠1)的元素,然后统计数量:
Conversation.aggregate([ // 可选:如果只想保留one=1或two=1的文档(避免count为0的文档),可以加这个$match阶段 { $match: { $or: [ { one: 1 }, { two: 1 } ] } }, { $project: { count: { $size: { $filter: { input: "$messages", cond: { $or: [ { $and: [ { $eq: ["$one", 1] }, { $ne: ["$$this.sender", 1] } ] }, { $and: [ { $eq: ["$two", 1] }, { $ne: ["$$this.sender", 1] } ] } ] } } } } } } ])
代码解释
- $match阶段(可选):先筛选出
one=1或two=1的文档,因为如果文档的这两个字段都不等于1,那最终的count必然为0,你可以根据需求决定是否保留这些文档。 - $project阶段:
- 使用
$filter遍历messages数组,$$this代表当前遍历到的数组元素; cond里的条件对应你的需求:要么文档的one是1且当前元素的sender不等于1,要么文档的two是1且当前元素的sender不等于1;- 最后用
$size获取过滤后的数组长度,也就是你要统计的数量。
- 使用
为什么之前的语句没有返回结果?
因为你把$or作为一个独立的聚合阶段,MongoDB无法识别这个阶段,所以整个聚合操作会报错或者返回空结果。按照上面的写法,就能正确统计每个文档中符合条件的messages元素数量了。
内容的提问来源于stack exchange,提问作者null
相关产品推荐
相关产品推荐

