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 usando la librería PHP de MongoDB.

Un cursor es un mecanismo que devuelve los resultados de una operación de lectura en lotes iterables. Los cursores reducen tanto el consumo de memoria como el número de solicitudes al servidor al mantener solo un subconjunto de documentos en cualquier momento, en lugar de devolver todos los documentos a la vez.

Cada vez que la librería de PHP de MongoDB realiza una operación de lectura usando el MongoDB\Collection::find() método, devuelve los documentos coincidentes en una instancia MongoDB\Driver\Cursor. La clase Cursor implementa la de PHP IteradorInterfaz que proporciona mayor control sobre la iteración y mayor compatibilidad con funciones PHP que trabajan con iterables. Los cursores de MongoDB solo admiten la iteración hacia adelante, por lo que no se puede rebobinar un cursor ni usar un foreach bucle varias veces.

Los ejemplos de esta guía utilizan la colección restaurants en la base de datos sample_restaurants de los conjuntos de datos de muestra de Atlas. Para acceder a esta colección desde tu aplicación PHP, instancia un MongoDB\Client que se conecte a un clúster Atlas y asigna el siguiente valor a tu variable $collection:

$collection = $client->sample_restaurants->restaurants;

Para saber cómo crear una implementación gratuita de MongoDB y cargar los conjuntos de datos de ejemplo, consulta la guía MongoDB Primeros Pasos.

La clase MongoDB\Driver\Cursor implementa la interfaz Iterator, por lo que puedes utilizar un bucle foreach para iterar a través de su contenido.

El siguiente ejemplo utiliza el método MongoDB\Collection::find() para recuperar todos los documentos cuyo valor del campo name es 'Dunkin' Donuts'. A continuación, imprime cada documento desde el cursor devuelto por el método find():

$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
foreach ($cursor as $doc) {
echo json_encode($doc), PHP_EOL;
}
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"}
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40363098"}
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40395071"}
...

Para recuperar un documento individual de un cursor, llama al método current() en una instancia MongoDB\Driver\Cursor. Este método devuelve el documento al que el cursor apunta inicialmente. Puedes seguir avanzando el cursor llamando al método next(), lo que instruye al cursor para que apunte al siguiente documento recuperado.

El siguiente ejemplo busca todos los documentos cuyo valor del campo name sea 'Dunkin' Donuts'. A continuación, imprime el primer documento recuperado llamando al método current() en un cursor:

$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
$cursor->rewind();
echo json_encode($cursor->current());
{"_id":{"$oid":"..."},..."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 desde un cursor, convierte el cursor en un arreglo utilizando cualquiera de los siguientes métodos:

  • MongoDB\\Driver\\Cursor::toArray(): Llamada a un objeto MongoDB\Driver\Cursor

  • iterator_to_array(): Pasa un objeto MongoDB\Driver\Cursor como parámetro

El siguiente ejemplo llama al método toArray() en un cursor para almacenar sus resultados en un arreglo:

$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
$resultArray = $cursor->toArray();

Si deseas que un cursor permanezca abierto después de que tu cliente lea su contenido inicial, puedes utilizar un cursor con seguimiento. Se recomienda usar cursores con seguimiento para consultar colecciones con tamaño fijo.

No puedes usar un bucle foreach para iterar un cursor con seguimiento, ya que el bucle termina después de leer el conjunto de resultados inicial del cursor. Si utilizas un segundo bucle foreach para seguir iterando el cursor con seguimiento, la librería de PHP intentará rebobinar el cursor y luego generará un error. En vez de eso, se deben usar los métodos de la interfaz Iterador para recuperar resultados de un cursor con seguimiento.

Para crear un cursor con seguimiento, define la opción cursorType en MongoDB\Operation\Find::TAILABLE en un arreglo. A continuación, pasa el arreglo como parámetro de opciones al método MongoDB\Collection::find().

Esta sección proporciona los siguientes scripts de ejemplo, que puedes ejecutar simultáneamente:

  1. Un script de productor que crea una colección con tamaño fijo e inserta documentos en ella

  2. Un script de consumidor que crea un cursor adaptable para leer documentos de la colección limitada

El siguiente ejemplo crea una colección con tamaño fijo llamada vegetables y espera 5 segundos antes de insertar un documento adicional en la colección:

$db = $client->db;
$db->createCollection(
'vegetables',
['capped' => true, 'size' => 1024 * 1024],
);
$vegetables = [
['name' => 'cauliflower', 'createdAt' => new MongoDB\BSON\UTCDateTime()],
['name' => 'zucchini', 'createdAt' => new MongoDB\BSON\UTCDateTime()],
];
$collection = $db->vegetables;
$result = $collection->insertMany($vegetables);
sleep(5);
$collection->insertOne(['name' => 'carrot', 'createdAt' => new MongoDB\BSON\UTCDateTime()]);

Mientras el anterior ejemplo de código se está ejecutando, use el siguiente código para crear un cursor con seguimiento y recuperar todos los documentos en la colección vegetables:

$cursor = $collection->find([], ['cursorType' => MongoDB\Operation\Find::TAILABLE]);
$cursor->rewind();
$docsFound = 0;
while ($docsFound < 3) {
if ($cursor->valid()) {
$doc = $cursor->current();
echo json_encode($doc), PHP_EOL;
$docsFound++;
}
$cursor->next();
}
{"_id":{"$oid":"..."},"name":"cauliflower","createdAt":{"$date":{"$numberLong":"..."}}}
{"_id":{"$oid":"..."},"name":"zucchini","createdAt":{"$date":{"$numberLong":"..."}}}
{"_id":{"$oid":"..."},"name":"carrot","createdAt":{"$date":{"$numberLong":"..."}}}

Este código imprime los dos documentos iniciales en la colección, pero el bucle while no se termina hasta recibir un tercer documento. El método next() se asegura de que el código espere los resultados adicionales del cursor.

Tip

Para obtener más información sobre los cursores con seguimiento, consulta cursores con seguimiento en el manual del servidor de MongoDB.

Para obtener más información sobre las operaciones de lectura, consulte el Retrieve Data guide.

Para obtener más información sobre cursores, véase las siguientes páginas en la documentación de la API de extensión:

Para obtener más información sobre el método find(), consulta la documentación de la API para MongoDB\Collection::find().

Volver

Valores únicos de campo

En esta página