按ID删除100M +文档的最快方法

时间:2015-03-01 00:55:58

标签: mongodb

我目前面临从数个数据库中删除100M +文档的数量,从100k文档到100M文档,总共约300M文档。此外,每个文档都包含其他集合中的引用,这些引用必须无效。我有一个要删除的所有文档的集合+ ID列表,目标是尽快删除它们,以便对用户产生最小的影响。

我目前的方法是通过{ _id: { $in: [] } }发送要删除的5k组,并以并行方式将更新发送到以相同分组方式引用这些文档的所有集合。事实证明这很慢,所以我正在寻找替代方案。

我刚刚读到了批量写入API,我想知道这是否是一个更好的解决方案。如果是这样,我很好奇最有效的方法是使用它。我应该像现在一样继续分组,但是在一次批量请求中一次发送多个组?我是否应该停止在查询中进行分组,而是使用批量请求作为我的组使用5k个别删除/更新命令?

2 个答案:

答案 0 :(得分:2)

根据您的要求(您有300万个文档,需要删​​除1/3)我会调查以下内容:

创建新集合,然后使用满足您要求的元素填充它。然后,删除以前的集合并重命名临时集合。

多一点解释。你有一个带有N个文件的集合A.您需要根据ID删除N / 3个文档。创建要删除的ID的哈希表。然后迭代集合,对于ID不在哈希值中的每个元素,将其保存在新的临时集合中。您可以将其保存在bulk insert

中进行改进

为什么我认为它会更快:当您使用索引时,每次搜索都需要O(log(n))时间,因此您可能会花费O(n * log(k))。在我的情况下,在哈希映射中搜索是O(1),因此我希望O(n)

答案 1 :(得分:2)

因为我们无法负担用户的停机时间并且解决方案是每天运行(尽管规模要小得多,因为我们正赶上第一次运行)但我无法使用Salvador Dali的解决方案。我最终将要删除的记录分组为1k组,并发送BulkWrite命令,每个记录包含一个delete()操作。与此同时,我发送了n个BulkWrite命令来取消对每条记录的引用,其中n是引用记录的集合数,以及每个BulkWrite请求具有1k个单独update()操作的位置,类似于delete()。这样做的速度相当快,所以我没有尝试通过调整BulkWrite命令中的操作次数来进一步优化。