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

MongoDB统计嵌套数组中各元素所在顶层文档数量

统计嵌套数组元素的顶层文档出现次数

需求:统计嵌套在数组型子文档的数组内的每个元素,分别存在于多少个顶层文档中,同一顶层文档内重复出现的元素仅计数一次。

文档示例

[{
  "title": "fruit mix 1",
  "fruit_details": [
    {
      "fruit_names": ["strawberry", "banana"],
      "category": "berries"
    },
    {
      "fruit_names": ["strawberry", "apple", "mango"],
      "category": "red"
    }
  ]
},{
  "title": "fruit mix 2",
  "fruit_details": [
    {
      "fruit_names": ["banana", "mango"],
      "category": "tropical"
    }
  ]
},{
  "title": "fruit mix 3",
  "fruit_details": [
    {
      "fruit_names": ["banana", "lemon"],
      "category": "yellow"
    },
    {
      "fruit_names": ["banana"],
      "category": "long"
    }
  ]
}]

期望结果

[{
  "_id": "banana",
  "count": 3
},{
  "_id": "mango",
  "count": 2
},{
  "_id": "lemon",
  "count": 1
},{
  "_id": "strawberry",
  "count": 1
},{
  "_id": "apple",
  "count": 1
}]

问题分析

你之前尝试的$setUnion用法有误,直接传入"$fruit_details.fruit_names"只会把多个fruit_names数组合并成数组集合,无法提取所有元素并在同一文档内去重,导致重复计数的问题。

正确聚合管道

db.collection.aggregate([
  // 展开fruit_details数组,每个子文档成为独立条目
  { $unwind: "$fruit_details" },
  // 展开每个fruit_details下的fruit_names数组,每个水果名称成为独立条目
  { $unwind: "$fruit_details.fruit_names" },
  // 按顶层文档_id和水果名称分组,确保同一文档内同一水果只保留一条
  {
    $group: {
      _id: {
        docId: "$_id",
        fruit: "$fruit_details.fruit_names"
      }
    }
  },
  // 按水果名称分组,统计出现的不同文档数量
  {
    $group: {
      _id: "$_id.fruit",
      count: { $sum: 1 }
    }
  },
  // 按计数降序、名称升序排序(可选)
  { $sort: { count: -1, _id: 1 } }
])

步骤说明

  1. 两次$unwind:先拆fruit_details数组,再拆fruit_names数组,把所有嵌套的水果名称提取成扁平化的条目。
  2. 第一次$group:以「顶层文档ID + 水果名称」为分组键,合并同一文档内重复的水果记录,确保每个文档每个水果仅保留一条。
  3. 第二次$group:以水果名称为分组键,统计对应的文档数量,得到该水果在多少个顶层文档中出现的次数。
  4. 排序:按计数降序、名称升序排列,让结果更直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:35:24