使用生成器在Mongo中遍历大型集合

5
我有一个包含50万多个文档的集合,存储在单个节点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()会推进光标。因此,每次调用都会丢失一个元素...
问题: 有没有办法修改这段代码,以便我可以检查next是否存在?Pymongo 3x不提供hasNext()和'alive' check 不能保证返回false。

0到1000等于[0,1,2,3......,999],下一个开始是1000但你会失去一个(可能是最后一个)。所以索引号永远不等于长度号。 - dsgdfg
能否这样说呢 first_result_in_batch = results.next(),从而捕获您当前正在丢弃的元素(如果有的话)?然后您将在for循环之前放置yield first_result_in_batch,从而按正确的顺序将该元素提供给调用者。(我不了解MongoDB,所以可能会漏掉一些东西。) - D-Von
2个回答

3
< p > .find() 方法需要额外的关键字参数。其中之一是 no_cursor_timeout ,您需要将其设置为 True 。 < /p >
cursor = collection.find({}, no_cursor_timeout=True)

您不需要编写自己的生成器函数。 find() 方法返回类似生成器的对象。


将超时设置为False会导致我不得不重启虚拟机...它就会卡住。 - zevij

1
为什么不使用


for result in results:
    yield result

for循环应该为您处理StopIteration


它确实会停止,但是我需要知道并处理迭代和跳过任务之外的部分(例如,获取前10,000个,处理,获取下一个10,000个进行处理等)。就像我说的那样,问题在于“停止”而不丢失数据。 - zevij
@dsgdfg 你错过了整个重点。我同意你已经有了1000个,但由于 next(),你刚刚丢掉了一个。我猜唯一的方法是执行“count”并将跳过/限制逻辑从迭代器中取出。 - zevij
@Patrick Haugh - 尽管我同意你的说法,但你忽略了一个问题,那就是要想获得正确的迭代行为并保证不超时和不“挂起”,就必须使用跳过和限制。问题在于,cursor.alive不能保证返回False,hasNext()不存在,如果使用next(),则会丢失一个元素...如上所述,我唯一能想到的方法是将跳过/限制逻辑从迭代器中取出... - zevij
1
MongoDB用户永远不会在游标/ RAM上保存1000个元素。在写入时设置所有所需值,这意味着仅处理最后一条记录。谁告诉你“不能将结果保存到Mongodb”?浪费资源和时间。但是也许您想要玩real_time数据记录,这需要将所有_id设置为“基于时间的ID”。mongodb上的find方法很垃圾。尝试像经典数据库一样使用“非表格数据库”。请使用其他数据库系统。MongoDB用户永远不会使用find函数,因为**db['I"am']['know']['where']['writing']['this']['data']**始终返回dataNone - dsgdfg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接