我正在尝试迭代这个循环:
for doc in coll.find()
我在第100,000个加号记录中收到以下错误。
File "build\bdist.win32\egg\pymongo\cursor.py", line 703, in next
File "build\bdist.win32\egg\pymongo\cursor.py", line 679, in _refresh
File "build\bdist.win32\egg\pymongo\cursor.py", line 628, in __send_message
File "build\bdist.win32\egg\pymongo\helpers.py", line 95, in _unpack_response
pymongo.errors.OperationFailure: cursor id '1236484850793' not valid at server
这个错误意味着什么?
答案 0 :(得分:38)
也许你的光标在服务器上超时了。要查看这是否是问题,请尝试设置timeout = False`:
for doc in coll.find(timeout=False)
请参阅http://api.mongodb.org/python/1.6/api/pymongo/collection.html#pymongo.collection.Collection.find
如果是超时问题,一种可能的解决方案是设置batch_size
(s。其他答案)。
答案 1 :(得分:35)
timeout=False
是危险的,不应该使用,因为与光标的连接可以保持打开无限时间,这将影响系统性能。 The docs specifically reference需要手动关闭游标。batch_size
设置为较小的数字会有效,但会产生很大的延迟问题,因为我们需要更频繁地访问数据库。在我的解决方案中,必须在光标上使用 sort :
done = False
skip = 0
while not done:
cursor = coll.find()
cursor.sort( indexed_parameter ) # recommended to use time or other sequential parameter.
cursor.skip( skip )
try:
for doc in cursor:
skip += 1
do_something()
done = True
except pymongo.errors.OperationFailure, e:
msg = e.message
if not (msg.startswith("cursor id") and msg.endswith("not valid at server")):
raise
答案 2 :(得分:25)
设置timeout=False
是一种非常糟糕的做法。摆脱游标id超时异常的更好方法是估计循环在10分钟内可以处理的文档数量,并提出保守的批量大小。这样,只要前一批中的文档用完,MongoDB客户端(在本例中为PyMongo)就必须偶尔查询一次服务器。这将使光标在服务器上保持活动状态,您仍将受到10分钟超时保护的保护。
以下是为光标设置批量大小的方法:
for doc in coll.find().batch_size(30):
do_time_consuming_things()
答案 3 :(得分:0)
您还可以使用以下方式强制进行评估:
for doc in list(coll.find())
答案 4 :(得分:0)