mongo常见问题


查询

  • 1、关于 pymongo.errors.CursorNotFound: Cursor not found 错误的解决方法:

1、关于 pymongo.errors.CursorNotFound: Cursor not found 错误的解决方法:

mongodb cursor id not valid error是一个超时错误。

mongo的查询,使用cursur查询的时候,如果没有设置batch size这个参数,那么mongo默认会返回101条数据,等这101条数据读取完了,也就是想读取第102条的时候,那么驱动会再去数据库读取下一批数据,这批数据不是用条数来限定的,而是最大限制为4m,放入内存,等该数据读完了再去取下一次4M; mongo本身为异步读写
当使用for c in col.find()时,数据库会一次性返回很多数据,如果处理这些数据的时间超过10分钟,一直没有像数据库获取后续数据,则会出现上述错误。

解决方案:

取消timeout限制,在结束遍历后close()游标。测试没有 timeout参数

1
2
3
4
5
cursor = coll.find(timeout=False)
for c in cursor:
    ...
    ...
cursor.close()

其他方案:

上面那个方案是我使用后成功的。还有几种方案,我尝试了一下,无效,不知道为什么。

解决方案2:

用batch_size()限制一次获取的数据量

1
for c in col.find().batch_size(20):

解决方案3:

用no_cursor_timeout参数去掉时间限制。注意后面要close()游标。

1
2
cursor=db.images.find(no_cursor_timeout=True)
for i in cursor:

cursor.close()
大批量数据插入:
当爬虫获取的数据量较大时,一条一条的写入MongoDB会过于消耗资源。
这时候就需要用到insert_many()方法,把数据放入列表中并批量插入,但是如果你为了数据不被重复建立了MongoDB的唯一索引,就可能会导致部分数据无法写入。
因为insert_many()默认是按序写入,一条数据写入失败,后面的数据就无法写入了。所以需要修改默认参数ordered。
当ordered=False时,数据就会被乱序并行插入,所以每个字典的插入操作互不影响

1
2
data_list = client.find({},{"_id":0})
client.insert_many(data_list,ordered=False)