1.使用聚合aggregate及管道group查询重复数据:
首先我的数据库是这样的(存在很多重复数据):
现在使用聚合aggregate查询重复数据:
db.ss_tests.aggregate([{$group : {_id : "$id", count : {$sum : 1}}}])
db.ss_tests.aggregate([{ $group: { _id: {id: '$id'},count: {$sum: 1}} }])
两条语句是一样的。只不过一个直接输出value,一个增加了key值。
*语法解释:使用聚合aggregate函数查询,使用索引_id进行查询,将id相同的使用管道$group将其分为一组,并使用sum计算一组的个数,将其赋值给count,输出
可以看到,我上面语句查询到的重复数据有的有20几条之多!
2.删除重复数据:
方法一,使用聚合解决:
db.ss_tests.aggregate([
{
$group: { _id: '$id',count: {$sum: 1},multiples: {$addToSet: '$_id'}}
},
{
$match: {count: {$gt: 1}}
}
]).forEach(function(doc){
doc.multiples.shift();
db.ss_tests.remove({_id: {$in: doc.dups}});
})
*语法解释:
1.使用聚合函数对ss_tests的id相同的文档(document)进行分组,使用$sum进行计算统计id相同的条数,并把条数赋值给count,使用$addToSet在返回结果中增加key为:multiples,value为:_id字段(因为聚合分组只会返回参与分组的字段);
演示:
(1)不适用addToset:db.ss_tests.aggregate([{ $group: { _id: {id: '$id'},count: {$sum: 1}} }])
结果很清晰,没有多余的数据:
{ "_id" : { "id" : "3714" }, "count" : 2 }
{ "_id" : { "id" : "3542" }, "count" : 1 }
{ "_id" : { "id" : "3457" }, "count" : 24 }
{ "_id" : { "id" : "3856" }, "count" : 23 }
{ "_id" : { "id" : "3261" }, "count" : 4 }
{ "_id" : { "id" : "3857" }, "count" : 23 }
{ "_id" : { "id" : "3849" }, "count" : 1 }
{ "_id" : { "id" : "3771" }, "count" : 23 }
{ "_id" : { "id" : "3321" }, "count" : 24 }
{ "_id" : { "id" : "2983" }, "count" : 24 }
{ "_id" : { "id" : "4141" }, "count" : 23 }
{ "_id" : { "id" : "4066" }, "count" : 23 }
{ "_id" : { "id" : "3918" }, "count" : 23 }
{ "_id" : { "id" : "3770" }, "count" : 23 }
{ "_id" : { "id" : "3696" }, "count" : 24 }
{ "_id" : { "id" : "3548" }, "count" : 24 }
{ "_id" : { "id" : "3519" }, "count" : 24 }
{ "_id" : { "id" : "3134" }, "count" : 24 }
{ "_id" : { "id" : "3129" }, "count" : 24 }
{ "_id" : { "id" : "3054" }, "count" : 24 }
2.使用addToset的范例:
单单是“_id:3054”的就有这么多数据,因为它会把每一个符合条件的“_id”加入对象中
{ "_id" : "3054", "count" : 24, "multiples" : [ ObjectId("605a7b8e00c31774b8b1d71f"), ObjectId("605a24b8484104570ceff2ca"), ObjectId("60556465ecc3c2203bcb77b3"), ObjectId("60550d8b1f84370319fddae4"), ObjectId("6054b6b1d47438654aeb098f"), ObjectId("605408f85c26901b6393f2a1"), ObjectId("60545fd3396fea44070dcb12"), ObjectId("605ad26bbe00311786e9a0bb"), ObjectId("6055bb3d0812c740b987fc40"), ObjectId("6057169a70776d3ef59e48ba"), ObjectId("60535aa7c3e533526a0d0e9d"), ObjectId("6053b21d9b938d73a90c1709"), ObjectId("605668e989cf997e62ec36c0"), ObjectId("6058c8c9b9015359d723678f"), ObjectId("60597709e1767e19b9b5b4e8"), ObjectId("605303ca9c9956350d1b5672"), ObjectId("60581b1d9aeace1a78562abe"), ObjectId("605612135f71606091ced0d4"), ObjectId("6056bfc0d8e4b71fd81c4318"), ObjectId("6057c4476b779b7b337cf037"), ObjectId("605871f3735c7a3af6bb659b"), ObjectId("60576d7058a77d5b9ad21916"), ObjectId("605920335ae8b5784cfbe330"), ObjectId("6059cde2206111394daa441e") ] }
2.再使用match匹配大id相同条数大于1的document;
此处演示不用addToSet下的结果,比较容易看:
演示范例: db.ss_tests.aggregate([{ $group: { _id: {id: '$id'},count: {$sum: 1}} }, {$match: {count: {$gt: 1}}}])
结果都是count大于1的结果:
{ "_id" : { "id" : "3714" }, "count" : 24 }
{ "_id" : { "id" : "3542" }, "count" : 24 }
{ "_id" : { "id" : "3457" }, "count" : 24 }
{ "_id" : { "id" : "3856" }, "count" : 23 }
{ "_id" : { "id" : "3261" }, "count" : 24 }
{ "_id" : { "id" : "3857" }, "count" : 23 }
{ "_id" : { "id" : "3849" }, "count" : 23 }
{ "_id" : { "id" : "3771" }, "count" : 23 }
{ "_id" : { "id" : "3321" }, "count" : 24 }
{ "_id" : { "id" : "2983" }, "count" : 24 }
{ "_id" : { "id" : "4141" }, "count" : 23 }
{ "_id" : { "id" : "4066" }, "count" : 23 }
{ "_id" : { "id" : "3918" }, "count" : 23 }
{ "_id" : { "id" : "3770" }, "count" : 23 }
{ "_id" : { "id" : "3696" }, "count" : 24 }
{ "_id" : { "id" : "3548" }, "count" : 24 }
{ "_id" : { "id" : "3519" }, "count" : 24 }
{ "_id" : { "id" : "3134" }, "count" : 24 }
{ "_id" : { "id" : "3129" }, "count" : 24 }
{ "_id" : { "id" : "3054" }, "count" : 24 }
3.使用js的forEach对返回的group组进行遍历,使用js方法的shift函数将每一个数组的重复的数据的第一个移除。此时再进行删除剩下重复的,因为前面的shift方法移除掉每一个重复数据的第一个,所以达到了保存的数据的都没有重复的目的
去除重复数据前,我的ss_tests数据集合中有这么多数据:
使用forEach去除数据后:
方法2:使用distinct方法去除重复数据:
此方法有些限制,摘抄官方文档一段话:
NOTE
Results must not be larger than the maximum BSON size. If your results exceed the maximum BSON size, use the aggregation pipeline to retrieve distinct values using the $group
operator, as described in Retrieve Distinct Values with the Aggregation Pipeline.
他说最大的数据量不能超过BSON的最大容量,即16MB,且要传入重复值的字符串,才能删除,此处不做展示,直接放弃。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。