Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Acceder a datos desde un cursor

En esta guía, puedes aprender cómo acceder a datos desde un cursor con PyMongo.

Un cursor es un mecanismo que devuelve los resultados de una operación de lectura en lotes iterables. Debido a que un cursor contiene solo un subconjunto de documentos en un momento dado, los cursores reducen tanto el consumo de memoria como el uso del ancho de banda de 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 Comenzar con PyMongo tutorial.

Para iterar sobre el contenido de un cursor, utiliza un bucle for, como se muestra en el siguiente ejemplo. Elija el Synchronous o la 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, convierta el cursor 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)

Por defecto, MongoDB cierra un cursor cuando el cliente ha agotado todos los resultados en el cursor. Para cerrar explícitamente un cursor, llama al método close() como se muestra en el siguiente ejemplo. Selecciona 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 con seguimiento para observar el registro de operaciones (oplog) de un miembro de un set de réplicas. Selecciona 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 aprender más sobre cursores con seguimiento, consulta la Guía de cursores con seguimiento 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