Visão geral
Neste guia, você pode aprender como acessar dados de um cursor usando a Biblioteca PHP do MongoDB .
Um cursor é um mecanismo que retorna os resultados de uma operação de leitura em lotes iteráveis. Os cursores reduzem o consumo de memória e o número de solicitações do servidor , mantendo apenas um subconjunto de documentos a qualquer momento, em vez de retornar todos os documentos de uma só vez.
Sempre que a Biblioteca PHP do MongoDB executa uma operação de leitura utilizando o MongoDB\Collection::find()
método, ela retorna os documentos correspondentes em uma MongoDB\Driver\Cursor
instância do. A Cursor
classe implementa a interface Iterador do PHP, que fornece mais controle sobre a iteração e maior compatibilidade com funções PHP que funcionam com iteráveis. Os cursores do MongoDB suportam apenas iteração para a frente, portanto, você não pode retroceder um cursor ou usar um foreach
loop várias vezes.
Dados de amostra
Os exemplos neste guia usam a collection restaurants
no banco de dados sample_restaurants
dos conjuntos de banco de dados de amostra do Atlas. Para acessar essa coleção a partir do seu aplicação PHP , instancie um MongoDB\Client
que se conecte a um Atlas cluster e atribua o seguinte valor à sua variável $collection
:
$collection = $client->sample_restaurants->restaurants;
Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de amostra, consulte o guia Iniciar com Atlas .
Acesse o conteúdo do cursor iterativamente
A classe MongoDB\Driver\Cursor
implementa a interface Iterator
, portanto, você pode usar um loop foreach
para iterar por seu conteúdo.
O exemplo a seguir usa o método MongoDB\Collection::find()
para recuperar todos os documentos nos quais o valor do campo name
é 'Dunkin' Donuts'
. Em seguida, ele imprime cada documento do cursor retornado pelo 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"} ...
Recuperar documentos individualmente
Para recuperar um documento individual de um cursor, chame o método current()
em uma instância MongoDB\Driver\Cursor
. Este método retorna o documento para o qual o cursor aponta inicialmente. Você pode continuar avançando o cursor chamando o método next()
, que instrui o cursor a ponto para o próximo documento recuperado.
O exemplo a seguir encontra todos os documentos em que o valor do campo name
é 'Dunkin' Donuts'
. Em seguida, ele imprime o primeiro documento recuperado chamando o método current()
em um cursor:
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']); $cursor->rewind(); echo json_encode($cursor->current());
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"}
Recuperar todos os documentos
Aviso
Se o número e o tamanho dos documentos retornados pela sua query excederem a memória disponível do aplicativo, seu programa falhará. Se você espera um conjunto de resultados grande, acesse o cursor iterativamente.
Para recuperar todos os documentos de um cursor, converta o cursor em uma array usando um dos seguintes métodos:
MongoDB\\Driver\\Cursor::toArray()
: Chame um objetoMongoDB\Driver\Cursor
iterator_to_array()
: Passe um objetoMongoDB\Driver\Cursor
como parâmetro
O exemplo seguinte chama o método toArray()
em um cursor para armazenar seus resultados em uma array:
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']); $resultArray = $cursor->toArray();
Cursores persistentes
Se quiser que um cursor permaneça aberto depois que o cliente ler o conteúdo inicial, você pode usar um cursor persistente. Recomendamos que você use cursores tailable para consultar coleções limitadas.
Você não pode usar um foreach
loop para iterar um cursor persistente, pois o loop termina após a leitura do conjunto de resultados inicial do cursor. Se você usar um segundo foreach
loop para continuar iterando o cursor persistente, a biblioteca PHP tentará retroceder o cursor e gerará um erro. Em vez disso, você deve usar métodos da interface do Iterator para recuperar resultados de um cursor persistente.
Para criar um cursor persistente, defina a opção cursorType
como MongoDB\Operation\Find::TAILABLE
em uma array. Em seguida, passe a array como um parâmetro de opções para o método MongoDB\Collection::find()
.
Exemplo de cursor tailable
Esta seção fornece os seguintes scripts de amostra, que você pode executar simultaneamente:
Um roteiro de produtor que cria uma collection limitada e insere documentos nela
Um script de consumidor que cria um cursor persistente para ler documentos da collection limitada
Criar e preencher uma coleção
O exemplo a seguir cria uma collection limitada chamada vegetables
e aguarda 5
segundos antes de inserir um documento adicional na collection:
$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()]);
Criar um cursor tailable
Enquanto o exemplo de código anterior estiver em execução, use o seguinte código para criar um cursor persistente e recuperar todos os documentos na coleção 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":"..."}}}
Esse código imprime os dois documentos iniciais na coleção, mas o loop while
não termina até receber um terceiro documento. O método next()
garante que o código aguarde os resultados adicionais do cursor.
Dica
Para saber mais sobre cursores tailable, consulte Cursores tailable no manual do MongoDB Server .
Informações adicionais
Para saber mais sobre operações de leitura, consulte o guia Recuperar dados .
Para saber mais sobre cursores, consulte as seguintes páginas na documentação da API da extensão:
Documentação da API
Para saber mais sobre o método find()
, consulte a documentação API para MongoDB\Collection::find()
.