文档菜单

文档首页开发应用程序Python 驱动程序PyMongo

从游标访问数据

本页内容

  • 概述
  • 迭代访问游标内容
  • 单独检索文档
  • 检索所有文档
  • 关闭游标
  • 可尾随游标
  • 故障排除

在本指南中,您可以了解如何使用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 构造函数提供无效参数,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 或更高版本,这将消除无关的错误。

MongoDB 中的游标如果长时间打开且没有任何操作,可能会在服务器上超时。这可能导致在尝试迭代游标时出现 CursorNotFound 异常。

← 检索不同的字段值