Docs Menu
Docs Home
/ /

Acceder a los datos desde un cursor

Las operaciones de lectura que devuelven varios documentos no devuelven inmediatamente todos los valores que coinciden con la consulta. Dado que una consulta puede coincidir con conjuntos de documentos muy grandes, estas operaciones devuelven un objeto llamado cursor, que hace referencia a los documentos identificados por la consulta. Un cursor recupera los documentos en lotes para reducir el consumo de memoria y el uso del ancho de banda de la red. Los cursores son altamente configurables y ofrecen múltiples paradigmas de interacción para diferentes casos de uso.

Las siguientes funciones devuelven directamente los cursores:

  • Collection.find()

  • Collection.aggregate()

  • Collection.listIndexes()

  • Collection.listSearchIndexes()

  • Db.aggregate()

  • Db.listCollections()

Otros métodos como Collection.findOne() y Collection.watch() utilizan cursores internamente y devuelven los resultados de las operaciones en lugar de un cursor.

Se pueden usar varios paradigmas de cursor para acceder a los datos. La mayoría permiten acceder a los resultados de la consulta documento por documento, abstrayendo la lógica de red y caché. Sin embargo, dado que los casos de uso difieren, otros paradigmas ofrecen patrones de acceso diferentes, como extraer todos los documentos coincidentes y colocarlos en una colección en la memoria de proceso.

Advertencia

No combine diferentes paradigmas de cursor en un solo cursor. Operaciones como hasNext() y toArray() modifican previsiblemente el cursor original. Si combina estas llamadas en un mismo cursor, podría obtener resultados inesperados.

Advertencia

Dado que las llamadas asincrónicas modifican directamente el cursor, ejecutarlas simultáneamente en un mismo cursor también puede causar un comportamiento indefinido. Espere siempre a que la operación asincrónica anterior se complete antes de ejecutar otra.

Nota

Cuando se llega al último resultado a través de la iteración o mediante una búsqueda inmediata, el cursor se agota, lo que significa que deja de responder a los métodos que acceden a los resultados.

Los cursores implementan la Interfaz AsyncIterator, que le permite utilizar cursores en for await...of bucles:

const cursor = myColl.find({});
console.log("async");
for await (const doc of cursor) {
console.log(doc);
}

Puede usar el método hasNext() para verificar si un cursor puede recuperar más datos y luego usar el método next() para recuperar el elemento siguiente del cursor:

const cursor = myColl.find({});
while (await cursor.hasNext()) {
console.log(await cursor.next());
}

Para casos de uso que requieren que todos los documentos coincidentes con una consulta se almacenen en memoria simultáneamente, utilice el método toArray(). Tenga en cuenta que un gran número de documentos coincidentes puede causar problemas de rendimiento o fallos si la operación excede las limitaciones de memoria. Considere usar la for await...of sintaxis para iterar los resultados en lugar de devolver todos los documentos a la vez.

const cursor = myColl.find({});
const allValues = await cursor.toArray();

Los cursores exponen el método stream() para convertirlos en flujos legibles por nodos. Estos flujos operan en el Modo de Objeto, que pasa objetos de JavaScript en lugar de búferes o cadenas a través de la pipeline.

const cursor = myColl.find({});
cursor.stream().on("data", doc => console.log(doc));

Como secuencias legibles, los cursores también admiten los eventos close, data, end y readable de la API de eventos:

const cursor = myColl.find({});
// the "data" event is fired once per document
cursor.on("data", data => console.log(data));

Para restablecer un cursor a su posición inicial en el conjunto de documentos devueltos, utilice rewind().

const cursor = myColl.find({});
const firstResult = await cursor.toArray();
console.log("First count: " + firstResult.length);
await cursor.rewind();
const secondResult = await cursor.toArray();
console.log("Second count: " + secondResult.length);

Los cursores consumen memoria y recursos de red tanto en la aplicación cliente como en la instancia conectada de MongoDB. Use close() para liberar los recursos de un cursor tanto en la aplicación cliente como en el servidor MongoDB, como se muestra en el siguiente ejemplo:

await cursor.close();

Recomendamos cerrar manualmente cualquier cursor no agotado que su aplicación ya no utilice para evitar fugas de recursos.

Tip

Gestión explícita de recursos

El controlador de Nodo.js admite de forma nativa la gestión explícita de recursos para MongoClient, ClientSession, ChangeStreams y cursores. Esta característica es experimental y está sujeta a cambios. Para aprender a utilizar la gestión explícita de recursos, consulta las Notas de versión v6.9.

Puedes cancelar operaciones de cursor utilizando una señal de aborto. Esto te puede ayudar a gestionar tus recursos liberando memoria y recursos de red que utiliza el cursor si ya no se necesitan.

Nota

Esta función es experimental. Al cancelar una señal, se cierra la conexión, lo que podría provocar un restablecimiento innecesario de la misma.

Puede pasar el comando signal a los siguientes métodos:

  • collection.find()

  • collection.findOne()

  • collection.aggregate()

  • collection.countDocuments()

  • db.listCollections()

  • db.command()

Para usar una señal de cancelación, cree una instancia AbortController y extraiga la signal del controlador. En este ejemplo de código, el proceso escucha una SIGINT (Ctrl+C) para activar el método abort(). Puede pasar la opción signal al método find() para cancelar la operación del cursor si la señal se activa, como se muestra en el siguiente ejemplo:

const controller = new AbortController();
const { signal } = controller;
process.on('SIGINT', () => controller.abort(new Error('^C pressed')));
try {
const cursor = myColl.find({}, { signal });
for await (const doc of cursor) {
console.log(doc);
}
} catch (error) {
if (error === signal.reason) {
console.error('Operation aborted:', error);
} else {
console.error('Unexpected error:', error);
}
}

Volver

Texto de query

En esta página