Docs Menu
Docs Home
/ /

Acceder a los datos desde un cursor

En esta guía, puede aprender cómo acceder a los datos de un cursor con PyMongo.

Un cursor es un mecanismo que devuelve los resultados de una operación de lectura en lotes iterables. Dado que un cursor solo contiene un subconjunto de documentos en un momento dado, reduce el consumo de memoria y el uso del ancho de banda de la red.

Siempre que PyMongo realiza una operación de lectura que devuelve varios documentos, automáticamente devuelve esos documentos en un cursor.

Los ejemplos de esta guía utilizan el sample_restaurants.restaurants colección de la Conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte Tutorial paraempezar a usar PyMongo.

Para iterar sobre el contenido de un cursor, utilice un bucle for, como se muestra en el siguiente ejemplo. Seleccione el Synchronous o pestaña Asynchronous para ver el código correspondiente:

results = collection.find()
for document in results:
print(document)
results = collection.find()
async for document in results:
print(document)

Recupere documentos de un cursor individualmente llamando al método next().

El siguiente ejemplo encuentra todos los documentos en una colección con un name valor de "Dunkin' Donuts". Luego imprime el primer documento en el cursor llamando al método next(). Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:

results = collection.find({ "name": "Dunkin' Donuts" })
print(results.next())
{'_id': ObjectId('...'), 'address': { ... }, 'borough': 'Bronx', 'cuisine': 'Donuts', 'grades': [...], 'name': "Dunkin' Donuts", 'restaurant_id': '40379573'}
results = collection.find({ "name": "Dunkin' Donuts" })
print(await results.next())
{'_id': ObjectId('...'), 'address': { ... }, 'borough': 'Bronx', 'cuisine': 'Donuts', 'grades': [...], 'name': "Dunkin' Donuts", 'restaurant_id': '40379573'}

Advertencia

Si la cantidad y el tamaño de los documentos devueltos por su consulta exceden la memoria disponible de la aplicación, el programa se bloqueará. Si espera un conjunto de resultados grande, acceda al cursor iterativamente.

Para recuperar todos los documentos de un cursor, conviértalo en un list, como se muestra en el siguiente ejemplo. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:

results = collection.find({ "name": "Dunkin' Donuts" })
all_results = list(results)
for document in all_results:
print(document)
results = collection.find({ "name": "Dunkin' Donuts" })
all_results = await to_list(results)
for document in all_results:
print(document)

De forma predeterminada, MongoDB cierra un cursor cuando el cliente ha agotado todos los resultados. Para cerrar un cursor explícitamente, llame al método close() como se muestra en el siguiente ejemplo. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:

results = collection.find()
...
results.close()
results = collection.find()
...
await results.close()

También puede instanciar un cursor en una instrucción with, como se muestra en el siguiente ejemplo. PyMongo cierra automáticamente el cursor al finalizar el bloque.

with collection.find() as cursor:
for document in cursor:
print(document)

Al consultar una colección limitada, puede usar un cursor adaptable que permanece abierto después de que el cliente agote los resultados de un cursor. Para crear un cursor adaptable con una colección limitada, especifique CursorType.TAILABLE_AWAIT en la cursor_type opción de un find() método.

El siguiente ejemplo utiliza un cursor adaptable para seguir el registro de operaciones de un miembro del conjunto de réplicas. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:

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)
oplog = client.local.oplog.rs
first = await 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:
async 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.
await asyncio.sleep(1)

Para obtener más información sobre los cursores adaptables, consulte la guía Cursores adaptables en el manual del servidor MongoDB.

PyMongo v3.8 o anterior genera un TypeError y un AttributeError si se proporcionan argumentos no válidos al constructor Cursor. El AttributeError es irrelevante, pero el TypeError contiene información de depuración, como se muestra en el siguiente ejemplo:

Exception ignored in: <function Cursor.__del__ at 0x1048129d8>
...
AttributeError: 'Cursor' object has no attribute '_Cursor__killed'
...
TypeError: __init__() got an unexpected keyword argument '<argument>'

Para solucionar esto, asegúrese de proporcionar los argumentos de palabras clave correctos. También puede actualizar a PyMongo v3.9 o posterior, lo que elimina el error irrelevante.

Los cursores en MongoDB pueden agotar el tiempo de espera en el servidor si han estado abiertos durante mucho tiempo sin que se les haya realizado ninguna operación. Esto puede generar una excepción CursorNotFound al intentar iterar sobre el cursor.

Volver

Valores únicos de campo

En esta página