La clase MongoDB\Driver\Cursor

(mongodb >=1.0.0)

Introducción

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().

Sinopsis de la Clase

final class MongoDB\Driver\Cursor implements MongoDB\Driver\CursorInterface {
/* Métodos */
final private __construct()
final public getId(): MongoDB\BSON\Int64
final public isDead(): bool
public key(): int
public next(): void
public rewind(): void
final public setTypeMap(array $typemap): void
final public toArray(): array
public valid(): bool
}

Historial de cambios

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.

Ejemplos

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ón maxAwaitTimeMS puede ser utilizada conjuntamente con tailable y awaitData para especificar la duración durante la cual el servidor debe bloquearse cuando alcance el final del conjunto de resultados.

Errores/Excepciones

Durante la iteración sobre el objeto Cursor, los datos BSON se convierten en variables PHP. Esta iteración puede provocar las siguientes excepciones:

Tabla de contenidos