我在Mongo中有一个集合,其中包含一个特定键的重复项,除了其中一个键,我需要删除它。 Map Reduce解决方案似乎并不清楚如何删除除一个重复之外的所有重复项。我正在使用Ruby,我怎么能以一种有效的方式做到这一点?我目前的解决方案速度令人难以置信!
我目前只是迭代重复键的数组并删除返回的第一个文档,但这只适用于每个键最多有1个重复文档且速度非常慢的情况。
dupes.each do |key|
$mongodb.collection("some_collection").remove($mongodb.collection("some_collection").find({key: key}).first)
end
答案 0 :(得分:2)
我认为您应该使用MongoDB ensureIndex()
来删除重复项。例如,在您的情况下,您想要删除重复的文档,给出密钥duplicate_key
,您可以这样做
db.duplicate_collection.ensureIndex({'duplicate_key' : 1},{unique: true, dropDups: true})
其中duplicate_collection
是您的重复文档所在的集合。如果存在重复文档给出特定密钥,则此操作仅保留单个文档。
操作完成后,如果您认为要删除索引,只需执行dropIndex
操作即可。有关详细信息,您可以搜索mongodb文档。
答案 1 :(得分:0)
许多解决方案都建议使用Map Reduce(这是快速而精细的),但我在Ruby中实现了一个看起来非常快的解决方案,并且可以轻松地从每个重复集中保留一个文档。
基本上,您可以通过将所有重复密钥添加到哈希中找到所有重复密钥,并且只要您在集合中找到重复密钥,就可以将该文档的ID添加到最后将用于批量删除的数组中。 / p>
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 } })
此方法的唯一问题是,如果密钥/重写ID的总列表无法存储在内存中,则可能无法正常工作。在这一点上,地图缩减解决方案可能是最好的。