mongodb cursor id无效错误

cod*_*ous 40 python mongodb

我试图遍历这个循环:

for doc in coll.find()
Run Code Online (Sandbox Code Playgroud)

我在第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
Run Code Online (Sandbox Code Playgroud)

这个错误是什么意思?

Ret*_*old 38

也许你的光标在服务器上超时了.要查看这是否是问题,请尝试设置timeout = False`:

for doc in coll.find(timeout=False)
Run Code Online (Sandbox Code Playgroud)

http://api.mongodb.org/python/1.6/api/pymongo/collection.html#pymongo.collection.Collection.find

如果是超时问题,一种可能的解决方案是设置batch_size(s.其他答案).

  • 常见问题解答表明你有这样的正确:http://api.mongodb.org/python/current/faq.html#what-does-operationfailure-cursor-id-not-valid-at-server-mean (2认同)

Ora*_*ran 35

  • 设置timeout=False是危险的并且永远不应该使用,因为与光标的连接可以保持打开无限时间,这将影响系统性能.文档专门引用了手动关闭游标的需要.
  • 将设置batch_size为较小的数字会起作用,但会产生很大的延迟问题,因为我们需要更频繁地访问数据库.
    例如:
    带有小批量的5M文档将花费数小时来检索默认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
Run Code Online (Sandbox Code Playgroud)


jie*_*eng 25

设置timeout=False是一种非常糟糕的做法.摆脱游标id超时异常的更好方法是估计循环在10分钟内可以处理的文档数量,并提出保守的批量大小.这样,只要前一批中的文档用完,MongoDB客户端(在本例中为PyMongo)就必须偶尔查询一次服务器.这将使光标在服务器上保持活动状态,您仍将受到10分钟超时保护的保护.

以下是为游标设置批量大小的方法:

for doc in coll.find().batch_size(30):
    do_time_consuming_things()
Run Code Online (Sandbox Code Playgroud)