MongoDB:如何用$match结合$expr查找数组字段存在交集的文档
问题:MongoDB聚合中用$match结合$expr筛选数组包含指定元素的文档
数据样本
[ { "_id": 1, "name": "Alice", "favorites": [ "apple", "banana", "cherry" ] }, { "_id": 2, "name": "Bob", "favorites": [ "banana", "orange" ] }, { "_id": 3, "name": "Charlie", "favorites": [ "apple", "cherry" ] } ]
需求:查找favorites字段包含apple或orange的文档。已知常规$match写法可行:
db.collection.aggregate([ { $match: { favorites: { $in: [ "apple", "orange" ] } } } ])
但尝试用$match结合$expr的写法返回空结果:
db.collection.aggregate([ { $match: { $expr: { $in: [ "$favorites", [ "banana", "orange" ] ] } } } ])//Returns no data
正确写法及原因
你的错误在于聚合中$in的参数逻辑和常规查询的$in相反,且直接传入数组作为$in的第一个参数不符合其使用场景——聚合里的$in是判断「单个值是否存在于数组中」,而非「数组是否包含某组值中的任意一个」。
要实现需求,有两种常用的$expr写法:
方法1:使用$anyElementTrue + $map
通过$map遍历favorites数组,判断每个元素是否在目标列表中,再用$anyElementTrue检查是否有至少一个匹配项:
db.collection.aggregate([ { $match: { $expr: { $anyElementTrue: { $map: { input: "$favorites", as: "item", in: { $in: [ "$$item", [ "apple", "orange" ] ] } } } } } } ])
方法2:使用$setIntersection + $ne
计算favorites和目标列表的交集,若交集不为空则说明存在匹配元素:
db.collection.aggregate([ { $match: { $expr: { $ne: [ { $setIntersection: [ "$favorites", [ "apple", "orange" ] ] }, [] ] } } } ])
两种写法都会返回_id为1、2、3的文档(其中1和3包含apple,2包含orange)。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

