×

mongoDB删除重复的数据 去重

96
超凡陆战队
2018.03.28 14:52* 字数 488

最近在工作上遇到需要清理鸡汤文中重复的数据,网上搜了一下,有不少方案,有用程序去重的,有用唯一索引来控制的,感觉都不是很方便,后来发现用下面这个非常方便;

db.Passages.aggregate([
    {
        $group:{_id:{content:'$content',endTime:'$endTime',startTime:'$startTime'},count:{$sum:1},dups:{$addToSet:'$_id'}}
    },
    {
        $match:{count:{$gt:1}}
    }

    ]).forEach(function(it){

         it.dups.shift();
            db.Passages.remove({_id: {$in: it.dups}});

    });

下面来解析:

  1. 使用aggregate聚合查询重复数据
  • $group中是查询条件,根据content、endTime、startTime字段来聚合相同的数据;
  • $count用来统计重复出现的次数, $match来过滤没有重复的数据;
  • $addToSet将聚合的数据id放入到dups数组中方便后面使用;
  1. 查询结果使用forEach进行迭代id来删除数据
  • shift()作用是剔除队列中第一条id,避免删掉所有的数据;

PS:注意函数的大小写,mongoDB是严格区分大小写的!!!


今天发版本执行脚本的时候发现在mongo2.4x的版本下面执行报错:

MongoDB shell version: 2.4.9
connecting to: 192.168.xxx.xxx:27017/xxx
Tue Apr  3 18:41:26.268 TypeError: Object [object Object] has no method 'forEach' at xxx.js:11
failed to load: xxx.js

先开始以为是2.4x版本如果没有查到重复数据造成forEach报错,加上try、catch手动捕获异常避免脚本执行失败,后来检查数据发现有重复数据的也依然进异常了,这下就懵逼了,难道2.4x版本aggregat返回的数据跟3.x版本的还不一样?

var list = db.Passages.aggregate([
    {
        $group:{_id:{content:'$content',endTime:'$endTime',startTime:'$startTime'},count:{$sum:1},dups:{$addToSet:'$_id'}}
    },
    {
        $match:{count:{$gt:1}}
    }

    ]);
print([JSON.stringify(list));

最后把查出的数据打印出来,发现返回的都是一个json对象不是数组,2.4x版本的数据是放在reslut字段下的,而3.x是放在·_batch·字段下(至于为什么可以直接forEach有待研究),当时心中一万只xxx奔腾而过,抱怨归抱怨bug还是要改的,当然就只能先判断一下版本罗。
经过反复修改测试,下面是最终修改结果。

var list = db.Passages.aggregate([
    {
        $group:{_id:{content:'$content',endTime:'$endTime',startTime:'$startTime'},count:{$sum:1},dups:{$addToSet:'$_id'}}
    },
    {
        $match:{count:{$gt:1}}
    }

    ]);
if(list._batch!=undefined){
        print('v3.4....')
        list.forEach(function(it){

        it.dups.shift();
        db.Passages.remove({_id: {$in: it.dups}});

    });
}else{
        print('v.2.4....')
        list.result.forEach(function(it){

        it.dups.shift();
        db.Passages.remove({_id: {$in: it.dups}});

    });

}
编程
Web note ad 1