(mongodb >=1.0.0)
La clase MongoDB\Driver\Cursor encapsula el resultado de un comando o de una consulta MongoDB, que puede ser devuelto por, respectivamente, MongoDB\Driver\Manager::executeCommand() o MongoDB\Driver\Manager::executeQuery().
Versión | Descripción |
---|---|
PECL mongodb 1.9.0 | Implementa Iterator. |
PECL mongodb 1.6.0 | Implementación de MongoDB\Driver\CursorInterface, que extiende Traversable. |
Ejemplo #1 Lectura de un conjunto de resultados
MongoDB\Driver\Manager::executeCommand() y MongoDB\Driver\Manager::executeQuery() ambos devuelven su(s) resultado(s) como un objeto MongoDB\Driver\Cursor. Este objeto puede ser utilizado para iterar dentro del conjunto de resultados de la comando o de la consulta.
Debido a que MongoDB\Driver\Cursor implementa la interfaz
Traversable, se puede simplemente iterar
sobre el conjunto de resultados con
foreach
.
<?php
$manager = new MongoDB\Driver\Manager();
/* Inserte documentos para que nuestra consulta devuelva información */
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['name' => 'Ceres', 'size' => 946, 'distance' => 2.766]);
$bulkWrite->insert(['name' => 'Vesta', 'size' => 525, 'distance' => 2.362]);
$manager->executeBulkWrite("test.asteroids", $bulkWrite);
/* Consulta para todos los elementos de la colección */
$query = new MongoDB\Driver\Query( [] );
/* Interroga la colección "asteroids" de la base de datos "test" */
$cursor = $manager->executeQuery("test.asteroids", $query);
/* $cursor contiene ahora un objeto que envuelve el conjunto de resultados.
* Utilice foreach() para iterar sobre todos los resultados */
foreach($cursor as $document) {
print_r($document);
}
?>
El resultado del ejemplo sería algo similar a:
stdClass Object ( [_id] => MongoDB\BSON\ObjectId Object ( [oid] => 5a4cff2f122d3321565d8cc2 ) [name] => Ceres [size] => 946 [distance] => 2.766 ) stdClass Object ( [_id] => MongoDB\BSON\ObjectId Object ( [oid] => 5a4cff2f122d3321565d8cc3 ) [name] => Vesta [size] => 525 [distance] => 2.362 }
Ejemplo #2 Lectura de un conjunto de resultados para un cursor en cola
Los » cursores en cola son un tipo especial de cursor MongoDB que permite al cliente leer algunos resultados y esperar hasta que más documentos se vuelvan disponibles. Estos cursores se utilizan principalmente con » Capped Collections y » Change Streams.
Aunque los cursores normales pueden ser recorridos una vez con
foreach
, este enfoque no funcionará con los
cursores en cola. Cuando foreach
se utiliza con un
cursor en cola, el bucle se detendrá al final del conjunto de resultados inicial.
Intentar continuar la iteración sobre el cursor con un segundo
foreach
lanzaría una excepción, ya que PHP intenta
rebobinar el cursor. Al igual que los objetos result en otros controladores
de base de datos, los cursores en MongoDB solo admiten la iteración hacia adelante, lo que significa que no pueden ser rebobinados.
Para leer continuamente desde un cursor en cola, el objeto Cursor debe ser envuelto con un IteratorIterator. Esto permite a la aplicación controlar directamente la iteración del cursor, evitar rebobinar accidentalmente el cursor y decidir cuándo esperar nuevos resultados o detener completamente la iteración.
Para demostrar un cursor en acción, se utilizarán dos scripts: un "Productor" y un "Consumidor". El script Productor creará una nueva colección plafonada utilizando el comando » Create y procederá a insertar un nuevo documento en esta colección cada segundo.
<?php
$manager = new MongoDB\Driver\Manager;
$manager->executeCommand('test', new MongoDB\Driver\Command([
'create' => 'asteroids',
'capped' => true,
'size' => 1048576,
]));
while (true) {
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['createdAt' => new MongoDB\BSON\UTCDateTime]);
$manager->executeBulkWrite('test.asteroids', $bulkWrite);
sleep(1);
}
?>
Con el script Productor aún en ejecución, un segundo script consumidor puede ser ejecutado para leer los documentos insertados utilizando un cursor en cola, indicado por las opciones tailable
y awaitData
a
MongoDB\Driver\Query::__construct().
<?php
$manager = new MongoDB\Driver\Manager;
$query = new MongoDB\Driver\Query([], [
'tailable' => true,
'awaitData' => true,
]);
$cursor = $manager->executeQuery('test.asteroids', $query);
$iterator = new IteratorIterator($cursor);
$iterator->rewind();
while (true) {
if ($iterator->valid()) {
$document = $iterator->current();
printf("Consumed document created at: %s\n", $document->createdAt);
}
$iterator->next();
}
?>
El script consumidor comenzará imprimiendo rápidamente todos los
documentos disponibles en la colección plafonada (como si
foreach
hubiera sido utilizado); sin embargo, no se
detendrá al final del conjunto de resultados inicial. Dado que
el cursor está en cola, la llamada a
IteratorIterator::next() se bloquea y espera resultados adicionales. IteratorIterator::valid() también se utiliza para verificar si realmente hay datos disponibles para leer en cada paso.
Nota: Este ejemplo utiliza la opción de consulta
awaitData
para indicar al servidor que bloquee durante un corto período (por ejemplo, un segundo) al final del conjunto de resultados antes de devolver una respuesta al controlador. Esto se utiliza para evitar que el controlador interrogue agresivamente al servidor cuando no haya resultados disponibles. La opciónmaxAwaitTimeMS
puede ser utilizada conjuntamente contailable
yawaitData
para especificar la duración durante la cual el servidor debe bloquearse cuando alcance el final del conjunto de resultados.
Durante la iteración sobre el objeto Cursor, los datos BSON se convierten en variables PHP. Esta iteración puede provocar las siguientes excepciones: