使用生成器迭代Mongo中的大型集合

时间:2016-09-21 02:19:13

标签: python mongodb pymongo pymongo-3.x

我有一个500K +文档的集合,存储在单个节点mongo上。偶尔我的pymongo cursor.find()因超时而失败。

虽然我可以将find设置为忽略超时,但我不喜欢这种方法。相反,我尝试了一个生成器(改编自this回答和this链接):

def mongo_iterator(self, cursor, limit=1000):
        skip = 0
        while True:
            results = cursor.find({}).sort("signature", 1).skip(skip).limit(limit)

            try:
                results.next()

            except StopIteration:
                break

            for result in results:
                yield result

            skip += limit

然后我使用以下方法调用此方法:

ref_results_iter = self.mongo_iterator(cursor=latest_rents_refs, limit=50000)
for ref in ref_results_iter:
    results_latest1.append(ref)

问题: 我的迭代器不会返回相同数量的结果。问题是next()使光标前进。因此,对于每次通话,我都会丢失一个元素......

问题: 有没有办法调整此代码,以便我可以检查下一个是否存在? Pymongo 3x不提供hasNext()和'alive'检查is not guaranteed来返回false。

2 个答案:

答案 0 :(得分:1)

为什么不使用

for result in results:
    yield result

for循环应该为你处理StopIteration

答案 1 :(得分:1)

.find()方法需要额外的关键字参数。其中一个是no_cursor_timeout,您需要将其设置为True

cursor = collection.find({}, no_cursor_timeout=True)

您无需编写自己的生成器功能。 find()方法返回类似于对象的生成器。