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

MongoDB千万级文档集合高效统计字段去重数量的方法

高效统计MongoDB大集合指定字段的去重数量

有一个包含超1000万条文档的MongoDB集合,文档结构如下:

[
  {
    //-- type and date
    "date": "2023-11-09",
    "type": "my_type",
    "resource": "2222"
  },
  {
    //-- type and date
    "date": "2023-11-09",
    "type": "my_type",
    "resource": "1111"
  },
  {
    //-- type and date
    "date": "2023-11-09",
    "type": "my_type",
    "resource": "1111"
  }
]

需要实现性能优异的查询,统计resource字段的去重数量,要求不可预计算统计结果,但可以给resource字段添加索引。

当前使用的聚合查询(存在性能与逻辑问题)

[
  {
    $sort:
      {
        resource: 1,
      },
  },
  {
    $group: {
      _id: null,
      distinctResources: {
        $addToSet: "$resource",
      },
    },
  },
  {
    $project: {
      total: {
        $size: ["$resource"],
      },
    },
  },
]

问题说明:$addToSet会将所有去重值加载到内存,千万级数据下极易触发内存溢出;$project中的$size引用错误,应指向$distinctResources而非$resource;额外的$sort也会增加不必要的性能开销。

期望输出结果

{
  "_id": null,
  "totalDistinct": 2 // 对应示例中的1111和2222
}

优化方案

1. 先给resource字段创建单键索引

这是提升查询性能的核心前提,索引可让MongoDB直接扫描索引键,避免全表扫描:

db.yourCollection.createIndex({ resource: 1 })

2. 最优聚合查询(内存友好+性能优异)

使用$group按resource分组,再用$count统计分组数量,这种方式仅遍历索引中的唯一值,无需加载大量数据到内存,完全适配千万级数据集:

[
  {
    $group: {
      _id: "$resource"
    }
  },
  {
    $count: "totalDistinct"
  }
]

备选方案(MongoDB 5.0+支持)

若需使用窗口函数实现,可参考以下写法,但内存占用高于上述方案:

[
  {
    $sort: { resource: 1 }
  },
  {
    $setWindowFields: {
      partitionBy: null,
      sortBy: { resource: 1 },
      output: {
        distinctCount: {
          $addToSet: "$resource",
          window: { documents: ["unbounded", "current"] }
        }
      }
    }
  },
  {
    $skip: { $subtract: [{ $count: {} }, 1] }
  },
  {
    $project: {
      totalDistinct: { $size: "$distinctCount" },
      _id: 0
    }
  }
]

不推荐的方式

distinct命令会返回所有去重值的数组,千万级数据下极易触发内存溢出,仅适合小数据量场景:

// 大数据量禁用
db.yourCollection.distinct("resource").length

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:35:31