-
需求:使用python连接mongo,遍历集合中的文档
-
错误:pymongo.errors.CursorNotFound: Cursor id 1234567890 not found
-
分析:
- 情况:遍历成功了很多,之后突然报错
- 百度:python中,针对mongo集合的find()方法会按批量从集合中取一定量(默认20条或101条<两种说法>)的数据,如果没有在规定时间(默认10分钟)内返回游标就会报这个错
- 参考:https://stackoverflow.com/questions/24199729/pymongo-errors-cursornotfound-cursor-id-not-valid-at-server
- 解决思路:
- 减少batch_size大小
- 关闭cursor超时自动断开
-
具体解决方法:
-
1、设置no_cursor_timeout = True,永不超时,游标连接不会主动关闭,需要手动关闭
- 注意:在for循环里删除col表中与当前doc数据一样的其他重复数据时,下次循环仍然会遇到这些重复数据。可以认为demos是已经取好的结果,放在缓存中了。
demos = db.col.find({},no_cursor_timeout = True)
for doc in demos:
db.col.delete_many({'table': doc['name']})
do_something()
demos.close() # 关闭游标
- 2、设置batch_size返回文档数,默认应该是20个文档,可以设置小一些
- 注意:在for循环里删除col表中与当前doc数据一样的其他重复数据时,下次循环不会遇到这些重复数据。可以认为这些删除操作会及时更新到还没循环到的数据中。
#每次只返回5个文档
for doc in db.col.find().batch_size(5):
db.col.delete_many({'table': doc['name']})
do_something()
注意:
1、第一种方法不建议,因为万一你的程序中间某个步骤卡住了又不报错,那么你的cursor也不会超时,这样不利于找出bug而且还会浪费大量的计算资源(只在batch_size(1)不起作用时使用)
2、第二种方法仍然可能会出现超过10分钟而没有返回的情况,具体可以去权衡10分钟和每批次取多少条数据,保证这么多条数据在10分钟内可以计算完并触发返回
参考链接:https://blog.csdn.net/myli_binbin/article/details/99675677
网友评论