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

如何用MongoDB聚合管道获取多文档数组字段的去重值合集

结论

这个需求完全可以通过MongoDB原生聚合管道实现,不需要应用层做额外计算,推荐用$facet阶段并行处理两个数组字段,避免多字段$unwind产生笛卡尔积导致的性能浪费。

实现逻辑
  • 配置两个独立的聚合分支,分别处理tags和dim_cm字段,分支间逻辑互不干扰
  • 每个分支先通过$unwind把对应数组拆成单条文档的单个值,再用$group搭配$addToSet自动收集跨文档的去重值
  • 最后调整输出结构,和预期格式对齐
聚合代码

假设集合名为items,可直接执行以下聚合语句:

db.items.aggregate([
  {
    $facet: {
      unique_tags: [
        { $unwind: "$tags" },
        // 如果需要过滤特定值比如plain,在这里加{ $match: { tags: { $ne: "plain" } } }即可
        {
          $group: {
            _id: null,
            values: { $addToSet: "$tags" }
          }
        },
        { $project: { _id: 0 } }
      ],
      unique_dim_cm: [
        { $unwind: "$dim_cm" },
        {
          $group: {
            _id: null,
            values: { $addToSet: "$dim_cm" }
          }
        },
        { $project: { _id: 0 } }
      ]
    }
  },
  {
    $project: {
      "tags去重合集": { $first: "$unique_tags.values" },
      "dim_cm去重合集": { $first: "$unique_dim_cm.values" }
    }
  }
])
返回结果

执行后返回的结果结构如下:

[
  {
    tags去重合集: ["blank", "red", "plain", "blue"],
    dim_cm去重合集: [14, 21, 22.85, 30, 10, 15.25]
  }
]

说明:你给出的预期tags结果里少了示例文档paper中包含的plain值,如果不需要这个值,按照代码注释里的位置加$match过滤即可。

补充说明
  • $addToSet操作符本身自带去重特性,不需要额外编写去重逻辑
  • 如果使用MongoDB 5.2及以上版本,可以在每个分支的$project前增加排序逻辑,对去重后的数组做排序,示例:{ $addFields: { values: { $sortArray: { input: "$values", sortBy: 1 } } } }
  • 数据量较大时,$facet并行处理的性能远高于连续$unwind两个数组再分组的写法,不会产生冗余的笛卡尔积数据。

内容的提问来源于stack exchange,提问作者Peanuts-83

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:15:39