You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:45:04