# A classe MongoDB\Driver\Cursor

(mongodb >=1.0.0)

## Introdução

A classe MongoDB\Driver\Cursor encapsula os resultados de um comando ou consulta MongoDB e podem ser retornados por MongoDB\Driver\Manager::executeCommand() ou MongoDB\Driver\Manager::executeQuery(), respectivamente.

## Resumo da classe

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

## Registro de Alterações

Versão | Descrição
--- | ---
PECL mongodb 1.9.0 | Implementa Iterator.
PECL mongodb 1.6.0 | Implementa MongoDB\Driver\CursorInterface, que estende Traversable.

## Exemplos

Exemplo #1 Lendo um conjunto de resultados

MongoDB\Driver\Manager::executeCommand() e MongoDB\Driver\Manager::executeQuery() ambos retornam seus resultados como um objeto MongoDB\Driver\Cursor. Este objeto pode ser usado para iterar sobre conjunto de resultados do comando ou consulta.

Como MongoDB\Driver\Cursor implementa a interface Traversable, pode-se simplesmente iterar pelo conjunto de resultados com `foreach`.

    <?php

    $manager = new MongoDB\Driver\Manager();

    /* Insere alguns documentos para que a consulta retorne informação */
    $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 todos os itens na coleção */
    $query = new MongoDB\Driver\Query( [] );

    /* Consulta a coleção "asteroids" do banco de dados "test" */
    $cursor = $manager->executeQuery("test.asteroids", $query);

    /* $cursor agora contém um objeto que envolve o conjunto de resultados. Pode-se
     * usar foreach() para iterar por todo o resultado */
    foreach($cursor as $document) {
        print_r($document);
    }

    ?>

O exemplo acima produzirá algo semelhante 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
    )

Exemplo #2 Lendo um conjunto de resultados com um cursor adaptável

» Cursores adaptáveis são um tipo especial de cursor no MongoDB que permite ao cliente ler alguns resultados e então esperar até que mais documentos fiquem disponíveis. Esses cursores são usado principalmente com » Coleções Limitadas e » Fluxos de Alterações.

Enquanto os cursores normais podem ser iterados com `foreach`, esse método não irá funcionar com cursores adaptáveis. Quando `foreach` é usado com um cursor adaptável, a repetição irá terminar quando alcançar o final do conjunto de resultados inicial. A tentativa de continuar a iteração no cursor com um segundo `foreach` lançaria uma exceção, já que o PHP tentaria retroceder o cursor. De forma similar aos objetos de resultados em outros drivers de bancos de dados, os cursores no MongoDB suportam apenas iteração para a frente, ou seja, eles não podem ser retrocedidos.

Para ler continuamente a partir de um cursor adaptável, o objeto Cursor deve ser encapsulado com um IteratorIterator. Isso permite que a aplicação controle diretamente a iteração do cursor, evite retroceder inadvertidamente o cursor e decida quando esperar por novos resultados ou interromper totalmente a iteração.

Para demonstrar um cursor adaptável em ação, serão utilizados dois scripts: um "produtor" e um "consumidor". O script produtor criará uma nova coleção limitada usando o comando » create e procederá à inserção de um novo documento nessa coleção a 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);
    }

    ?>

Com o script produtor ainda em execução, um segundo script consumidor pode ser executado para ler os documentos inseridos usando um cursor adaptável, indicado pelas opções `tailable` e `awaitData` para o método 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("Documento consumido criado em: %s\n", $document->createdAt);
        }

        $iterator->next();
    }

    ?>

O script consumidor começará mostrando rapidamente todos os documentos disponíveis na coleção limitada (como se `foreach` tivesse sido usado); entretanto, ele não terminará ao atingir o final do conjunto de resultados inicial. Como o cursor pode ser seguido, chamar IteratorIterator::next() bloqueará e aguardará resultados adicionais. IteratorIterator::valid() também é usado para verificar se realmente há dados disponíveis para leitura em cada etapa.

> Nota: Este exemplo usa a opção de consulta `awaitData` para instruir o servidor a bloquear por um curto período (por exemplo, um segundo) no final do conjunto de resultados antes de retornar uma resposta ao driver. Isso é usado para evitar que o driver faça uma sondagem agressiva no servidor quando não houver resultados disponíveis. A opção `maxAwaitTimeMS` pode ser usada em conjunto com `tailable` e `awaitData` para especificar a quantidade de tempo que o servidor deve bloquear quando atingir o final do o conjunto de resultados.

## Erros/Exceções

Ao iterar sobre o objeto cursor, os dados BSON são convertidos em variáveis ​ ​PHP. Esta iteração pode causar as seguintes exceções:

- Lança uma MongoDB\Driver\Exception\InvalidArgumentException se uma classe no mapa de tipos não puder ser instanciada ou não implementar MongoDB\BSON\Unserializable.
- Lança uma exceção MongoDB\Driver\Exception\UnexpectedValueException se a entrada não contiver exatamente um documento BSON. Os possíveis motivos incluem, mas não estão limitados a, BSON inválido, dados extras (depois de ler um documento BSON) ou um erro inesperado da » libbson.

## Índice

- MongoDB\Driver\Cursor::__construct — Cria um novo cursor (não utilizado)
- MongoDB\Driver\Cursor::current — Retorna o elemento atual
- MongoDB\Driver\Cursor::getId — Retorna o ID para este cursor
- MongoDB\Driver\Cursor::getServer — Retorna o servidor associado a este cursor
- MongoDB\Driver\Cursor::isDead — Verifica se o cursor está esgotado ou pode ter resultados adicionais
- MongoDB\Driver\Cursor::key — Retorna o índice do resultado atual dentro do cursor
- MongoDB\Driver\Cursor::next — Avança o cursor para o próximo resultado
- MongoDB\Driver\Cursor::rewind — Retrocede o cursor para o primeiro resultado
- MongoDB\Driver\Cursor::setTypeMap — Define um mapa de tipos a ser usado para desserialização BSON
- MongoDB\Driver\Cursor::toArray — Retorna um array contendo todos os resultados deste cursor
- MongoDB\Driver\Cursor::valid — Verifica se a posição atual no cursor é válida

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open