从游标访问数据
概述
在本指南中,您可以学习如何使用PyMongo从游标访问数据。
游标是一种机制,它可以以可迭代的批次形式返回读取操作的结果。由于游标在任何给定时间只保留文档的一个子集,因此游标可以减少内存消耗和网络带宽的使用。
当PyMongo执行返回多个文档的读取操作时,它会自动将这些文档以游标的形式返回。
示例数据
本指南中的示例使用来自sample_restaurants.restaurants
集合的Atlas示例数据集。要了解如何创建免费的MongoDB Atlas集群并加载数据集,请参阅PyMongo入门.
迭代访问游标内容
要迭代游标内容,请使用如下示例中的for
循环
results = collection.find() for document in results: print(document)
单独检索文档
通过调用next()
方法单独从游标检索文档。
以下示例查找所有具有name
值为"Dunkin' Donuts"
的文档。然后通过调用next()
方法打印游标中的第一个文档。
results = collection.find({ "name": "Dunkin' Donuts" }) print(results.next())
{'_id': ObjectId('...'), 'address': { ... }, 'borough': 'Bronx', 'cuisine': 'Donuts', 'grades': [...], 'name': "Dunkin' Donuts", 'restaurant_id': '40379573'}
检索所有文档
警告
如果查询返回的文档数量和大小超过了可用应用程序内存,则您的程序将崩溃。如果您预期结果集很大,请迭代访问游标。
要检索游标中的所有文档,请将游标转换为如下示例中的list
。
results = collection.find({ "name": "Dunkin' Donuts" }) all_results = list(results) for document in all_results: print(document)
关闭游标
默认情况下,MongoDB 在客户端耗尽游标中的所有结果时关闭游标。要显式关闭游标,请调用以下示例中的 close()
方法。
results = collection.find() ... results.close()
可滚动游标
在查询有界集合时,您可以使用在客户端耗尽游标中的结果后仍然保持打开的 可滚动游标。要使用有界集合创建可滚动游标,请在 find()
方法的 cursor_type
选项中指定 CursorType.TAILABLE_AWAIT
。
以下示例使用可滚动游标跟踪副本集成员的 oplog。
oplog = client.local.oplog.rs first = oplog.find().sort('$natural', pymongo.ASCENDING).limit(-1).next() print(first) ts = first['ts'] while True: cursor = oplog.find({'ts': {'$gt': ts}}, cursor_type=pymongo.CursorType.TAILABLE_AWAIT) while cursor.alive: for doc in cursor: ts = doc['ts'] print(doc) # You end up here if the find() method returns no documents, or if # no new documents are added to the collection for more than 1 second. time.sleep(1)
有关可滚动游标的更多信息,请参阅 MongoDB 服务器手册中的 可滚动游标指南。
故障排除
光标对象没有属性 '_Cursor__killed'
PyMongo v3.8或更早版本,如果你向光标构造函数提供无效参数,将引发一个 TypeError
和一个 AttributeError
。这个 AttributeError
是无关紧要的,但 TypeError
包含了以下示例中的调试信息。
Exception ignored in: <function Cursor.__del__ at 0x1048129d8> ... AttributeError: 'Cursor' object has no attribute '_Cursor__killed' ... TypeError: __init__() got an unexpected keyword argument '<argument>'
要修复此问题,请确保您提供正确的关键字参数。您还可以升级到PyMongo v3.9或更高版本,这将消除无关的错误。
"CursorNotFound 光标id在服务器上无效"
如果MongoDB中的光标在服务器上长时间打开且没有任何操作,则可能超时。当你尝试遍历光标时,可能会导致 CursorNotFound
异常。