我目前有一个长时间运行的操作(在 Python + Celery 中运行),它遍历大约 43,000,000 个元素的整个 Mongo 集合,并在不对这些元素进行任何更改的情况下对这些元素进行分析。
随着此集合的增长,操作开始花费更长的时间(显然),现在定期失败,通常是由于不同数据库的超时。
我想将此操作拆分为几个较小的操作(可能仅对几百万个元素进行操作),并且我想知道生成将执行拆分的查询的最佳方法。我在这个集合上只有一个索引,它是_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()
需要很长时间 - 基本上与实际执行分析一样长!有没有更好的方法可以做到这一点?
,skip()
可能会很慢。可以改为使用批处理的最后一_id
来查询下一个批处理来执行范围查询。像这样:
db.<collection>.find({ "_id" : { $gte: prev_batch_last_id } } ).sort( { _id : 1 } ).limit(limit);
您必须自己将批处理的最后一个 id 存储到变量中。