mongodb去除重复的数据(二)

前天因为工作需要,开始着手对数据库中两千多万的数据中其中一个字段重复的数据进行去重。

原本使用一些测试的数据测试后,前天写的那个方法是可行的,但是当面对这个两千万的真实数据时,我却发现这方法有些不顶用了,最终只好又经过若干次的尝试,总算成功去重。

最终总结一下整个过程:

1、这个方法就是上一篇所讲的,利用mongodb的游标dbcursor和while循环的方式。

var res=db.test.find();
while(res.hasNext()){
      var res1=db.test.find();
      var re=res.next();
      while(res1.hasNext()){
              var re1=res1.next();
              if(re.age==re1.age){
                   db.test.remove({"age":re1.age});
               }
       }
       db.test.insert(re);
}

      原本我用了10000调数据进行测试,循环完毕后,就如预期一样只剩下1条数据。但是面对两千万的数据后,执行到一半就报错,并且一直卡在那里。

      我也不知道这情况究竟算是正常还是不正常,反正是等了半天的时间还是卡在那里,整个集合的数据也没有任何的变化。

      我想大概是一次性处理的数据太多了吧,我的循环那样执行下去,就需要循环两千万乘以两千万次,这个次数是在国语庞大,于是只好采取迂回的措施,把两千万拆分成20个集合,一个集合只装一百万。

      但是即便是一百万的数据,当我在执行这个方法时,还是卡在了那里。 于是我不禁就想,难到我要把20个集合再拆分成四十个集合,一个只装五十万?

      四十个集合,这工作量貌似有点太大,我选择无奈的放弃。

2、第一种方法失败的情况下,我只好另寻他途,然后便想到了唯一索引的方法。

    唯一索引的dropDups可以在建立索引时删除重复的数据,我想这个总应该是可行的吧。然而事实却证明我还是错了,最终还是以失败告终。

    在我执行如下方法建立唯一索引的时候,又是屡屡报错,并给我意外退出!     

db.alarm1.ensureIndex({"msgContent":1},{"unique":true,dropDups:true})

  

  直接在建立索引的时候删除数据无法达到目的,我只好再次采用迂回的方式,在一个全新的空集合中建立一个索引 :

   

 db.alarmBack.ensureIndex({"msgContent":1},{"unique":true})

    然后再把数据重新的导入到这个已经存在了唯一索引的集合中,我想应该可以了吧。

    但是,无奈的是,又失败了!

    因为我从生产数据库导出的数据用了mongodump的方式,所以导入的时候也用的mongorestore的方式,而这个方式实际上是恢复数据,在恢复数据的同时,连索引也一起恢复了。

    最让我抓狂的是,恢复索引也就罢了,竟然还在恢复的时候把我建的唯一索引给干掉了!这样一来,唯一索引没了,自然无法达到去重的目的,方法再次以失败告终。

    我不知道mongodump和mongorestore是否有相关参数可以指定不要索引,有空了一定要试一下(太坑了吧)。

3、上述两个方法都失败了,第二个方法失败的同时,我就想到要试一下另外一种导入和导出的方法:mongoimport和mongoexport。

    我隐约记得这两个方法导入导出的时候速度好像比mongodump和mongorestore慢,但是现在没有办法的情况下只好一试。

    但是事实证明这个方法在这种情况下居然可行,最终我使用第二种方法中的第二种方式,先在空白集合中建一个唯一索引,然后导入要去重的数据,成功的对这两千多万的数据去重。

    不过真的是慢啊,单纯的导入,我用mongodump连mongoimport一半的时间都没用到,不知道是否是因为姿势不对,暂且也不想去管它了!

    任务结束,但是心中还留下一些疑问,我想如果第二种方法中我导出的元数据是没有索引的,那么当我导入的时候,不知道它是否还会把我原本的唯一索引干掉;还有就是,或许直接用java代码处理导出的文件也可以,甚至可能更快,不过暂时有别的事情,也就不做尝试了。

时间: 2024-12-30 18:35:29

mongodb去除重复的数据(二)的相关文章

mongodb去除重复的数据

里边的内容在某些情况下不可行,可以参考下一篇. 今天出现了一个新的需求,有个部门需要拿到mongodb中的数据,要求去掉其中一个字段内容相同的数据. 虽然mongodb中有distinct来去重,但是和mysql的distinct不同的是,mysql中能用distinct * 返回整条记录的信息,而mongodb的distinct我却只是返回去重的那个字段的数据(或许mongodb也可以返回整条,但是我不知道). mysql中的distinct返回完整记录: mongodb中distinct去重

sql 去除重复数据(多字段)

问题描述 sql 去除重复数据(多字段) 我现在有个表 表里面有ID No,Pass 然后根据No,Pass相同的数据,保留Max(ID)数据,删除其他,如何做? 我是这么做的,不知道行不行 delete Min(ID),CAST(No AS VARCHAR)+CAST(Pass AS VARCHAR) from Table group by No, Pass having count(*) > 1 解决方案 可以用distinct或者group by一下 解决方案二: 试一下 DELETE F

如何去除my sql 数据表里一个字段的重复数据?中间用竖线分割开了,下附截图。

问题描述 如何去除my sql 数据表里一个字段的重复数据?中间用竖线分割开了,下附截图. 解决方案 1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select * from people where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1) 2.删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowi

读取excel去除重复数据,然后在存入数据库

问题描述 读取excel去除重复数据,数据量比较大,考虑执行效率问题,求大神给出最好解决方案 解决方案 解决方案二:如果你没有技术讨论,那么请把帖子发到"项目外包"论坛.免费"求"人,是一点诚意也没有的.解决方案三:你好!你可以在先Excel里面去除重复,再数据导入!这种方法不行吗?解决方案四:在查询Excel的时候直接去掉不行吗?和在数据库中一样用distinct解决方案五:可用第三方dll读取excel数据后进行去重然后存放到数据库中.aspose.cells读

java-Java导入excel文档,如何去除重复数据?

问题描述 Java导入excel文档,如何去除重复数据? 以下是我的导入excel工具类 public class StuExcelUtil { public static List<Student> redexcel(File file) throws Exception{ List<Student> list=new ArrayList<Student>(); InputStream input=new FileInputStream(file); Workbook

sql 表连接数据去重-sql 表连接后数据去除重复的内容

问题描述 sql 表连接后数据去除重复的内容 有个A表 订单号 入住人 1 张1 1 王1 2 张2 3 张3 有个B表 订单号 入住房间号 1 201 1 202 两个表的订单号是相同的 现在想得到表 订单号 入住人 房间号 1 张1 201 1 王1 202 2 张2 null 3 张3 null 请问改如何写 解决方案 关键问题是你的订单号比如1,入住了两个人,分别开了两个房间,但问题是哪个人是201房间,哪个人是202房间没有对应.这个人和房间的对应关系是怎样的? 解决方案二: 这是同一

mysql数据库去除重复数据

问题描述 mysql数据库去除重复数据 现在存在一个比赛信息 数据表(matchInfo),里面的字段有 id,MatchName,MatchTime,master,guest,现在是因为写入数据库的时候会出现重复数据,请问一下应该怎么过滤?sql语句怎么写? 解决方案 select distinct matchtime,matchname,master,guest from matchinfo 解决方案二: 通过分组查询可以简单的实现 select * from matchInfo group

Angularjs的ng-repeat中去除重复数据的方法_AngularJS

本文实例讲述了Angularjs的ng-repeat中去除重复数据的方法.分享给大家供大家参考,具体如下: 一.JS: ngApp.filter('unique', function () { return function (collection, keyname) { var output = [], keys = []; angular.forEach(collection, function (item) { var key = item[keyname]; if (keys.index

comboBox 绑定数据列 怎么去除重复

问题描述 用C#做hotelmanagesystem的时候comboBox绑定了数据库里一个列,但是不能去除重复的项怎么去除重复的项:我是手动绑定的,用的vs2005 解决方案 解决方案二:写SQL查询的时候用Distinct要害字去掉重复数据:SELECTDISTINCTCOL_NAMEFROMTABLE1GROUPBYCOL_NAME解决方案三:推荐在查询时去掉重复的解决方案四:你要帮定总要查询的吧,直接在查询语句里面限制就可以了OKIN1的方法就可以了解决方案五:填充的时候SQL语句用个g