问题
最近在数据库里写一段代码时发现
docs = db.web_materials_check.find({"pretty_formula":'MnO2'},{"struct_id":True,"relaxed_structure":True}) # web_materials_check 是数据库中collection的名字
ids = [i["struct_id"] for i in docs]
if len(ids) == 0:
db.web_materials_check.insert_one(insertdoc)
# 插入一个document,只做示意
else:
for doc in docs:
print(doc["relaxed_structure"])
# 对检索返回的 relaxed_structure 做进一步操作
然而此时却发现并没有返回任何relaxed_structure
信息
原因
pymongo里的find返回的是Cursor实例,并且只能进行一次迭代操作,所以在刚开始的第一个for
对其进行迭代操作后,Cursor就已经失效了。官方文档中是这么写的:
Future iterating performed on this cursor will cause new queries to be sent to the server, even if the resultant data has already been retrieved by this cursor.
解决方案
此时我们有两种解决方案
在第二个for之前使用rewind函数:
Rewind this cursor to its unevaluated state. Reset this cursor if it has been partially or completely evaluated. Any options that are present on the cursor will remain in effect.
docs = db.web_materials_check.find({"pretty_formula":'MnO2'},{"struct_id":True,"relaxed_structure":True})
ids = [i["struct_id"] for i in docs]
if len(ids) == 0:
db.web_materials_check.insert_one(insertdoc)
else:
docs.rewind() #此时docs将回到初始状态#
for doc in docs:
print(doc["relaxed_structure"])
此时将返回正常的relaxed_structure
信息
使用list方法将Cursor转化储存起来
docs = list(db.web_materials_check.find({"pretty_formula":'MnO2'},{"struct_id":True,"relaxed_structure":True}))
ids = [i["struct_id"] for i in docs]
if len(ids) == 0:
db.web_materials_check.insert_one(insertdoc)
else:
for doc in docs:
print(doc["relaxed_structure"])
此时所有的检索返回数据将会存入内存,故也不会存在Cursor丢失的问题了