我目前有一个长期运行的操作(在Python + Celery中运行),它遍历整个Mongo集合,包含大约43,000,000个元素,并对元素进行分析,而不对这些元素进行任何更改。
随着此集合的增长,操作开始需要更长时间(显然),并且现在通常由于超时到另一个数据库而定期失败。
我想将此操作拆分为几个较小的操作 - 可能仅运行几百万个元素 - 我想知道生成查询的最佳方法是否会进行拆分。我在这个集合上只有一个索引及其_id
。
显而易见的答案似乎是:
# This is executed in parallel on different servers
def doAnalysis(skipped,limit)
db.<collection>.find().skip(skipped).limit(limit)
...
# This is the parent task
elemsToAnalyze = db.<collection>.find().count()/10;
for i in range(0,10:
doAnalysis(elemsToAnalyze * i, elemsToAnalyze)
但事实证明.skip()
需要长时间 - 基本上与实际执行分析一样长!有更好的方法吗?
答案 0 :(得分:1)
skip()
可能会非常慢。您可以使用批次的最后_id
来查询下一批,从而进行范围查询。像这样:
db.<collection>.find({ "_id" : { $gte: prev_batch_last_id } } ).sort( { _id : 1 } ).limit(limit);
您必须自己将批次的最后一个ID存储到变量中。