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
/ /
Query

Iterar un cursor en mongosh

La db.collection.find() El método devuelve un cursor. Para acceder a los documentos, es necesario iterarlo. Sin embargo, en, si el cursor devuelto no está asignado a una variable mediante mongosh la var palabra clave, se itera automáticamente hasta 20 veces []1 para imprimir hasta los primeros 20 documentos de los resultados.

Los siguientes ejemplos describen formas de iterar manualmente el cursor para acceder a los documentos o utilizar el índice del iterador.

En mongosh, cuando asignes el cursor devuelto por el método find() a una variable usando la palabra clave var, el cursor no itera automáticamente.

Puedes llamar a la variable cursor en la shell para iterar hasta 20 veces [1] y mostrar los documentos coincidentes, como se muestra en el siguiente ejemplo:

var myCursor = db.users.find( { type: 2 } );
myCursor

También puedes usar el método de cursor next() para acceder a los documentos, como en el siguiente ejemplo:

var myCursor = db.users.find( { type: 2 } );
while (myCursor.hasNext()) {
print(tojson(myCursor.next()));
}

Como asistente de impresión alternativa, considera el método asistente printjson() para sustituir print(tojson()):

var myCursor = db.users.find( { type: 2 } );
while (myCursor.hasNext()) {
printjson(myCursor.next());
}

Puedes usar el método cursor forEach() para iterar el cursor y acceder a los documentos, como en el siguiente ejemplo:

var myCursor = db.users.find( { type: 2 } );
myCursor.forEach(printjson);

Consulta Métodos de cursor de JavaScript y tu documentación del driver para obtener más información sobre los métodos de cursor.

[1](1, 2) Puedes configurar el atributo DBQuery.shellBatchSize para cambiar la cantidad de documentos desde el valor por defecto de 20.

En mongosh, puedes usar el método toArray() para iterar por el cursor y devolver los documentos en un arreglo, como en el siguiente ejemplo:

var myCursor = db.inventory.find( { type: 2 } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];

El método toArray() carga en la RAM todos los documentos devueltos por el cursor; el método toArray() agota el cursor.

Adicionalmente, algunos controladores proporcionan acceso a los documentos utilizando un índice en el cursor (es decir, cursor[index]). Este es un atajo para primero llamar al método toArray() y luego usar un índice en el arreglo resultante.

Considera el siguiente ejemplo:

var myCursor = db.users.find( { type: 2 } );
var myDocument = myCursor[1];

El myCursor[1] es equivalente al siguiente ejemplo:

myCursor.toArray() [1];

A partir de MongoDB 5.0, los cursores creados dentro de una sesión de cliente se cierran cuando la correspondiente sesión de servidor finaliza con el comando killSessions, si la sesión expira o si el cliente ha agotado el cursor.

Por defecto, las sesiones del servidor tienen un tiempo de expiración de 30 minutos. Para cambiar el valor, configure el parámetro localLogicalSessionTimeoutMinutes al iniciar mongod.

Los cursores que no se abran en una sesión se cierran automáticamente después de 10 minutos de inactividad, o si el cliente ha agotado el cursor. Para sobrescribir este comportamiento en mongosh, puedes usar el método cursor.noCursorTimeout():

var myCursor = db.users.find().noCursorTimeout();

Después de configurar la noCursorTimeout opción, debe cerrar el cursor manualmente con o agotando los resultados del cursor.close() cursor.

Consulta tu documentación del driver para obtener información sobre cómo configurar la opción noCursorTimeout.

A medida que un cursor devuelve documentos, otras operaciones pueden ejecutarse en segundo plano y afectar los resultados, dependiendo del nivel de consistencia de lectura. Para más detalles, consulte Aislamiento de lectura, coherencia y actualidad.

El servidor MongoDB devuelve los resultados de la query en lotes. La cantidad de datos en el lote no superará el tamaño máximo de documentos BSON. Para anular el tamaño por defecto del lote, consulte batchSize() y limit().

Novedades en la versión 3.4: Las operaciones de tipo find(), aggregate(), listIndexes y listCollections pueden devolver un máximo de 16 megabytes por agrupar. batchSize() puede aplicar un límite menor, pero no uno mayor.

find() y las operaciones aggregate() tienen un tamaño de lote inicial de 101 documentos por defecto. Las operaciones posteriores de getMore realizadas sobre el cursor resultante no tienen un tamaño de lote por defecto, por lo que están limitadas únicamente por el tamaño del mensaje de 16 megabytes.

Para los queries que incluyen una operación de ordenación sin un índice, el servidor debe cargar todos los documentos en memoria para realizar la ordenación antes de devolver cualquier resultado.

A medida que se itera a través del cursor y se llega al final del lote devuelto, si hay más resultados, cursor.next() realizará un getMore operation para recuperar el siguiente lote. Para ver cuántos documentos quedan en el lote mientras se recorre el cursor, se puede usar el método objsLeftInBatch(), como en el siguiente ejemplo:

var myCursor = db.inventory.find();
var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;
myCursor.objsLeftInBatch();

El método db.serverStatus() devuelve un documento que incluye un campo metrics. El campo metrics contiene un campo metrics.cursor con la siguiente información:

  • número de cursores caducados desde el último reinicio del servidor

  • número de cursores abiertos con la opción DBQuery.Option.noTimeout configurada para evitar el tiempo de espera tras un periodo de inactividad

  • número de cursores abiertos "fijados"

  • número total de cursores abiertos

Considere el siguiente ejemplo que llama al método db.serverStatus() y accede al campo de resultados metrics y luego al campo cursor del campo metrics:

db.serverStatus().metrics.cursor

El resultado es el siguiente documento:

{
"timedOut" : <number>
"open" : {
"noTimeout" : <number>,
"pinned" : <number>,
"total" : <number>
}
}

Tip

Volver

Snapshots de larga duración

En esta página