如何使用Mongo聚合获取基于Tin字段的所有非唯一数据
MongoDB聚合查询:获取基于Tin字段的所有重复完整记录
问题描述
我需要用MongoDB聚合从指定集合中检索所有基于Tin字段的非唯一数据。目前能通过以下查询获取重复计数,但还需要拿到对应的完整重复数据记录。
现有查询代码:
db.Demo.aggregate([ { "$group": { "_id": "$Tin", "count": { "$sum": 1 } } }, { "$project": { "Vin": "$_id", "_id": 0, "count": "$count" } }, { "$match": { "count": { "$gt": 1 } } } ])
示例集合数据
[ { "Tin": "5051", "Status": "DOCUMENTED", "Region": "ECE", "ActionDateTime": ISODate("2022-08-21T00:46:24.000+00:00"), "FM": "XYZ" }, { "Tin": "5051", "Status": "DOCUMENTED", "Region": "ECE", "ActionDateTime": ISODate("2022-08-21T00:46:24.000+00:00"), "FM": "XYZ" }, { "Tin": "5055", "Status": "DOCUMENTED", "Region": "ECE", "ActionDateTime": ISODate("2022-08-21T00:46:24.000+00:00"), "FM": "XYZ" }, { "Tin": "5055", "Status": "DOCUMENTED", "Region": "ECE", "ActionDateTime": ISODate("2022-08-21T00:46:24.000+00:00"), "FM": "XYZ" }, { "Tin": "5052", "Status": "DOCUMENTED", "Region": "CHN", "ActionDateTime": ISODate("2022-08-21T00:46:24.000+00:00"), "FM": "XYZ" }, { "Tin": "5053", "Status": "DOCUMENTED", "Region": "AMAP", "ActionDateTime": ISODate("2022-08-21T00:46:24.000+00:00"), "FM": "XYZ" } ]
期望输出
获取所有Tin字段重复的完整数据记录:
[ { "ActionDateTime": ISODate("2022-08-21T00:46:24Z"), "FM": "XYZ", "Region": "ECE", "Status": "DOCUMENTED", "Tin": "5055" }, { "ActionDateTime": ISODate("2022-08-21T00:46:24Z"), "FM": "XYZ", "Region": "ECE", "Status": "DOCUMENTED", "Tin": "5055" }, { "ActionDateTime": ISODate("2022-08-21T00:46:24Z"), "FM": "XYZ", "Region": "ECE", "Status": "DOCUMENTED", "Tin": "5051" }, { "ActionDateTime": ISODate("2022-08-21T00:46:24Z"), "FM": "XYZ", "Region": "ECE", "Status": "DOCUMENTED", "Tin": "5051" } ]
解决方案
修改聚合管道,在分组阶段保留所有匹配的文档,之后筛选出重复组并展开文档:
db.Demo.aggregate([ // 按Tin分组,统计数量并保存所有对应文档 { "$group": { "_id": "$Tin", "count": { "$sum": 1 }, "docs": { "$push": "$$ROOT" } } }, // 筛选出重复的组(count>1) { "$match": { "count": { "$gt": 1 } } }, // 展开保存的文档数组,得到每条完整记录 { "$unwind": "$docs" }, // 投影只保留原始文档内容(可选,去掉_id、count等分组字段) { "$replaceRoot": { "newRoot": "$docs" } } ])
步骤说明:
- $group:按
Tin字段分组,用$sum统计每组数量,$push: "$$ROOT"把每组的所有原始文档存入docs数组。 - $match:过滤出数量大于1的分组(即存在重复的Tin)。
- $unwind:将
docs数组展开,每个文档成为单独的记录。 - $replaceRoot:把展开后的文档设为根文档,去掉分组阶段产生的
_id和count字段,只保留原始数据结构。
内容的提问来源于stack exchange,提问作者San K
相关产品推荐
相关产品推荐

