2013-04-12 85 views
0

我在Mongo中有一個集合,其中包含一個特定鍵上的重複項,我需要刪除其中的一個。 Map Reduce解決方案似乎沒有清楚說明如何刪除除重複項之外的所有項。我正在使用Ruby,我如何以一種有效的方式來做到這一點?我目前的解決方案令人難以置信的慢!如何使用ruby查找並刪除重複的mongo文檔

我目前只是迭代重複鍵的數組,並刪除返回的第一個文檔,但這隻適用於每個鍵最多有1個重複文檔並且它非常慢。

dupes.each do |key| 
    $mongodb.collection("some_collection").remove($mongodb.collection("some_collection").find({key: key}).first) 
end 

回答

0

很多解決方案的建議的Map Reduce(這是快速和精細),但我實現了在Ruby中的解決方案似乎是相當快速,以及可輕鬆從每個重複組離開一個文檔。

基本上,您可以通過將所有重複鍵添加到散列中找到所有重複鍵,並且每當您在該集合中找到重複鍵時,都會將該文檔的ID添加到數組中,您將在最後使用批量刪除。

all_keys = {} 
dupes = [] 
    dupe_key = "some_key" 

$mongodb.collection("some_collection").find.each do |doc| 
    all_keys[doc[dupe_key]].present? ? dupes << doc["_id"] : asins[doc[dupe_key]] = 1 
end 

$mongodb.collection("some_collection").remove({_id: {"$in" => dupes } }) 

這種方法的唯一問題是,如果key/dupe id的總列表不能存儲在內存中,它可能不會工作。地圖縮小解決方案在這一點上可能是最好的。

1

我想你應該使用MongoDB ensureIndex()刪除重複項。例如,你的情況,你要刪除的文件的副本給關鍵duplicate_key,你可以做

db.duplicate_collection.ensureIndex({'duplicate_key' : 1},{unique: true, dropDups: true}) 

其中duplicate_collection是你重複的文檔集合。如果有重複的文檔給出特定的密鑰,此操作將只保留單個文檔。

操作完成後,如果您認爲要刪除索引,只需執行dropIndex操作即可。有關詳細信息,可以搜索mongodb文檔。

+1

這對我來說不起作用,因爲我的集合中有太多的文檔被複制,並且我得到了錯誤「索引構建中的dropDups = true太多了」。 – Musicalmindz

+0

@Musicalmindz然後,你可以建立一個基於舊集合的新集合。首先,你得到給定鍵的不同值列表,然後使用'find_one'方法迭代鍵,然後將檢索到的文檔保存到一個集合中,然後刪除舊的文檔:) –

+0

這絕對是一個選項但我們想要完成這項工作。 – Musicalmindz