天天看點

mongodb去除重複的資料(二)

前天因為工作需要,開始着手對資料庫中兩千多萬的資料中其中一個字段重複的資料進行去重。

原本使用一些測試的資料測試後,前天寫的那個方法是可行的,但是當面對這個兩千萬的真實資料時,我卻發現這方法有些不頂用了,最終隻好又經過若幹次的嘗試,總算成功去重。

最終總結一下整個過程:

1、這個方法就是上一篇所講的,利用mongodb的遊标dbcursor和while循環的方式。

      原本我用了10000調資料進行測試,循環完畢後,就如預期一樣隻剩下1條資料。但是面對兩千萬的資料後,執行到一半就報錯,并且一直卡在那裡。

      我也不知道這情況究竟算是正常還是不正常,反正是等了半天的時間還是卡在那裡,整個集合的資料也沒有任何的變化。

      我想大概是一次性處理的資料太多了吧,我的循環那樣執行下去,就需要循環兩千萬乘以兩千萬次,這個次數是在國語龐大,于是隻好采取迂回的措施,把兩千萬拆分成20個集合,一個集合隻裝一百萬。

      但是即便是一百萬的資料,當我在執行這個方法時,還是卡在了那裡。 于是我不禁就想,難到我要把20個集合再拆分成四十個集合,一個隻裝五十萬?

      四十個集合,這工作量貌似有點太大,我選擇無奈的放棄。

2、第一種方法失敗的情況下,我隻好另尋他途,然後便想到了唯一索引的方法。

    唯一索引的dropdups可以在建立索引時删除重複的資料,我想這個總應該是可行的吧。然而事實卻證明我還是錯了,最終還是以失敗告終。

    在我執行如下方法建立唯一索引的時候,又是屢屢報錯,并給我意外退出!     

  直接在建立索引的時候删除資料無法達到目的,我隻好再次采用迂回的方式,在一個全新的空集合中建立一個索引 :

    然後再把資料重新的導入到這個已經存在了唯一索引的集合中,我想應該可以了吧。

    但是,無奈的是,又失敗了!

    因為我從生産資料庫導出的資料用了mongodump的方式,是以導入的時候也用的mongorestore的方式,而這個方式實際上是恢複資料,在恢複資料的同時,連索引也一起恢複了。

    最讓我抓狂的是,恢複索引也就罷了,竟然還在恢複的時候把我建的唯一索引給幹掉了!這樣一來,唯一索引沒了,自然無法達到去重的目的,方法再次以失敗告終。

    我不知道mongodump和mongorestore是否有相關參數可以指定不要索引,有空了一定要試一下(太坑了吧)。

3、上述兩個方法都失敗了,第二個方法失敗的同時,我就想到要試一下另外一種導入和導出的方法:mongoimport和mongoexport。

    我隐約記得這兩個方法導入導出的時候速度好像比mongodump和mongorestore慢,但是現在沒有辦法的情況下隻好一試。

    但是事實證明這個方法在這種情況下居然可行,最終我使用第二種方法中的第二種方式,先在空白集合中建一個唯一索引,然後導入要去重的資料,成功的對這兩千多萬的資料去重。

    不過真的是慢啊,單純的導入,我用mongodump連mongoimport一半的時間都沒用到,不知道是否是因為姿勢不對,暫且也不想去管它了!

    任務結束,但是心中還留下一些疑問,我想如果第二種方法中我導出的中繼資料是沒有索引的,那麼當我導入的時候,不知道它是否還會把我原本的唯一索引幹掉;還有就是,或許直接用java代碼處理導出的檔案也可以,甚至可能更快,不過暫時有别的事情,也就不做嘗試了。