MongoDB聚合中使用$mod报错,如何实现数组元素取模筛选?
MongoDB聚合管道筛选数组中存在指定条件元素的文档
问题背景
集合中文档结构如下:
{ "grades": [ { "grade": "A", "score": 8 }, {"grade": "A", "score": 7 } ] }
需求:筛选出grades数组中存在score被7整除(余数为0)的文档。
已知用find可以实现的方案:
db.restaurants.find( {"grades.score" : {$mod : [7,0]} }, {"restaurant_id" : 1,"name":1,"grades":1} );
自己编写的聚合方案报错:
db.restaurants.aggregate([ { "$match": { "$expr": {"$in": [0, [ { $mod: [ "$grades.score", 7 ] } ] ]} } }, ])
报错信息:
PlanExecutor error during aggregation :: caused by :: $mod only supports numeric types, not array and int
错误原因
"$grades.score"会返回一个数组类型的值,而$mod运算符仅支持数值类型输入,无法直接对数组执行取模运算,因此触发报错。
正确聚合实现方案
方案1:$map + $in
通过$map遍历grades.score数组,对每个元素执行取模运算生成余数数组,再用$in判断0是否存在于余数数组中:
db.restaurants.aggregate([ { "$match": { "$expr": { "$in": [ 0, { "$map": { "input": "$grades.score", "as": "score", "in": { "$mod": ["$$score", 7] } } } ] } } } ])
方案2:$map + $anyElementTrue
通过$map将每个score取模后与0比较,生成布尔值数组,再用$anyElementTrue判断数组中是否存在true(即存在符合条件的元素):
db.restaurants.aggregate([ { "$match": { "$expr": { "$anyElementTrue": { "$map": { "input": "$grades.score", "as": "score", "in": { "$eq": [{ "$mod": ["$$score", 7] }, 0] } } } } } } ])
两种方案都能遍历数组中所有元素,判断是否存在符合条件的score,进而筛选出目标文档。
内容的提问来源于stack exchange,提问作者Wrapper
相关产品推荐
相关产品推荐

