如何用MongoDB聚合管道查找重复数据?

雨明大大_3339

雨明大大_3339

2026-09-02

235人浏览

原创

直接用$group+$match可查重复值,但需注意分组键必须写为"$field"、预过滤null值、大数据量时必须加allowdiskuse:true,否则易漏查或卡死。

如何用mongodb聚合管道查找重复数据?

直接用 $group + $match 就能查出重复值,但必须注意分组键写法、null 干扰和内存限制,否则要么漏掉真重复,要么查询直接卡死。

查单字段重复:_id 必须写成 "$field"

常见错误是把 _id: "email" 写成字面量字符串,结果所有文档被分到同一个组里。正确写法是带 $ 符号的字段引用。

  • _id 必须设为 "$email",不是 "email"{ email: "$email" }
  • count{ $sum: 1 },别用 { $count: {} }(仅 MongoDB 5.0+ 支持,旧版会报错)
  • 字段可能为 null 或缺失时,$group 会把它们全归入 _id: null 组——如果业务上不算重复,得提前过滤:{ $match: { email: { $exists: true, $ne: null } } }

示例(查 users 中重复的 email):

db.users.aggregate([
  { $group: { _id: "$email", count: { $sum: 1 } } },
  { $match: { count: { $gt: 1 } } }
])

查多字段组合重复:_id 必须是对象,不能拼字符串

比如要查 namephone 联合重复,不能用 $concat 拼接——一旦某个字段为 null,整个结果变 null,所有记录挤进同一组。

TTS Free Online免费文本转语音
TTS Free Online免费文本转语音

一款在线免费文本转语音工具,可将输入的文字转换成语音,并提供包括普通话和部分方言在内的多种声音选择。

下载
  • 正确写法:_id: { name: "$name", phone: "$phone" },MongoDB 按字段结构精确比对
  • 若字段含空格或大小写不一致,先加 $addFields 标准化,例如:{ $addFields: { cleanPhone: { $trim: { input: "$phone" } } } }
  • 避免用 $toString 强转类型,不同字段类型(如 Number vs String)会导致分组不匹配

示例(查 orders 中相同 user_id + product_id 的重复下单):

db.orders.aggregate([
  { $group: { _id: { user_id: "$user_id", product_id: "$product_id" }, count: { $sum: 1 } } },
  { $match: { count: { $gt: 1 } } }
])

大数据量下必须加 allowDiskUse: true

MongoDB 聚合默认内存上限 100MB,$group 阶段遇到高基数字段(比如千万级用户查 email)会直接报错:Sort exceeded memory limit 或中断执行。

  • allowDiskUse: true 是调用 aggregate() 时的选项,不是 pipeline 阶段——Node.js 驱动里要传在第二个参数位置:collection.aggregate(pipeline, { allowDiskUse: true })
  • 分片集群上尤其要加,因为 $group 会把所有匹配文档拉到 mongos 节点归并,内存压力更大
  • 加了之后查询变慢是正常的,但至少能跑完;若仍超时,优先缩小输入范围,比如加时间条件:{ $match: { createdAt: { $gte: ISODate("2025-01-01") } } }

想拿到重复项的完整文档?别用 $group

如果目标不是统计重复次数,而是找出所有重复的原始文档(比如要删掉其中几条),$group 会丢数据——它只输出每个分组一条结果。

  • 真正要“获取所有重复文档”,应该移除 $group,改用 $lookup 自关联或两阶段查询:先用聚合找出重复值列表,再用 $in 查原始文档
  • 或者在 $group 阶段用 $addToSet: "$_id" 记录 ID 列表,再用 $lookup 关联回原集合(但要注意内存和性能)
  • Spring Data MongoDB 中误用 TypedAggregation.group("field") 会导致结果去重,本质是把聚合当成了去重工具,而非查找工具

最容易被忽略的是:分片集群中唯一索引只在单个分片生效,$group 查出来的重复,很可能就是因路由不均导致的“合法重复”。这种场景下,查只是第一步,后续必须检查分片键设计是否合理。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mongodb

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

695

5

mongodb启动命令
mongodb启动命令

MongoDB 是一种开源的、基于文档的 NoSQL 数据库管理系统。本专题提供mongodb启动命令的文章,希望可以帮到大家。

2023.08.08

2294

5

MongoDB删除数据的方法
MongoDB删除数据的方法

MongoDB删除数据的方法有删除集合中的文档、删除整个集合、删除数据库和删除指定字段等。本专题为大家提供MongoDB相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.19

2144

5

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4069

19

mongodb有哪些应用领域
mongodb有哪些应用领域

mongodb 的应用领域涵盖广泛,包括内容管理系统、社交媒体、分析、移动应用、物联网、金融科技、医疗保健和广告技术等领域,因其灵活性、可扩展性和易用性而广受欢迎。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

938

6

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

6312

6

mongodb安装失败如何彻底删除
mongodb安装失败如何彻底删除

彻底删除 mongodb 安装失败的步骤:1、停止和禁用 mongodb 服务;2、删除配置文件、数据目录和日志文件;3、删除 mongodb 二进制文件;4、卸载 mongodb 套件(如果通过软件包管理器安装);5、删除 mongodb 用户、组和目录;6、重启系统。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

575

6

mongodb与mysql好用推荐
mongodb与mysql好用推荐

mongodb 适用于非结构化数据、高扩展性和灵活查询(如网站内容管理、社交媒体),而 mysql 适用于结构化数据、强数据一致性和联接查询(如电子商务、银行系统)。

2024.04.02

1869

9

mongodb数据库的优势有哪些
mongodb数据库的优势有哪些

mongodb 数据库以其灵活、可扩展和高性能而闻名。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.08

2091

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MongoDB 教程
MongoDB 教程

共17课时 | 6.2万人学习

黑马云课堂mongodb实操视频教程
黑马云课堂mongodb实操视频教程

共11课时 | 3.5万人学习

MongoDB 教程
MongoDB 教程

共42课时 | 61.2万人学习