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

MongoDB聚合查询:将数组中匹配的元素追加为文档字段

解决方案:在聚合结果中追加匹配的数组元素

没问题,这个需求完全可以实现!你原来用codes.$的写法不生效,是因为这个语法仅适用于MongoDB的查询投影阶段,没法直接在聚合的$addFields里使用。下面给你两种实用的实现方式:

场景1:每个文档的codes数组仅有一个匹配元素

如果你的文档里codes数组只会有一个元素和输入的array匹配(就像你给出的示例那样),可以用$setIntersection + $first的组合,写法更简洁:

const array = ['a', 'b', 'c'];
await collection.aggregate([
  { $match: { codes: { $in: array } } },
  { 
    $addFields: {
      matchedField: {
        $first: { $setIntersection: ["$codes", array] }
      }
    }
  }
]).toArray();

原理说明:

  • $setIntersection会计算codes数组和输入array的交集,得到两者共有的元素(示例里就是["b"])
  • $first取交集数组的第一个元素,正好就是你需要的单个匹配值

场景2:每个文档的codes数组可能有多个匹配元素

如果你的文档里codes数组可能存在多个和array匹配的元素,想要把所有匹配元素都返回的话,直接用$setIntersection即可:

const array = ['a', 'b', 'c'];
await collection.aggregate([
  { $match: { codes: { $in: array } } },
  { 
    $addFields: {
      matchedField: { $setIntersection: ["$codes", array] }
    }
  }
]).toArray();

这种情况下,matchedField会是一个包含所有匹配元素的数组(比如如果文档codes是["b", "c"],返回的matchedField就是["b", "c"])

另一种替代方案:使用$filter

如果你更倾向于显式过滤的逻辑,也可以用$filter来实现,效果和第一种场景一致:

const array = ['a', 'b', 'c'];
await collection.aggregate([
  { $match: { codes: { $in: array } } },
  { 
    $addFields: {
      matchedField: {
        $first: {
          $filter: {
            input: "$codes",
            cond: { $in: ["$$this", array] }
          }
        }
      }
    }
  }
]).toArray();

原理说明:

  • $filter遍历codes数组,只保留满足$in条件的元素(即属于输入array的元素)
  • $first取过滤后的第一个元素,得到单个匹配值

用上面任意一种方法,都能得到你期望的结果:

{ "color": "red", "codes": [ "b" ], "matchedField": "b" }

内容的提问来源于stack exchange,提问作者user8555937

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 21:22:31