Acessar dados de um cursor
Nesta página
Visão geral
As operações de leitura que retornam vários documentos não retornam imediatamente todos os valores correspondentes à query. Como uma query pode potencialmente corresponder a conjuntos muito grandes de documentos, essas operações dependem de um objeto chamado cursor. Um cursor obtém documentos em lotes para reduzir o consumo de memória e o uso da largura de banda da rede. Os cursores são altamente configuráveis e oferecem vários paradigmas de interação para diferentes casos de uso.
As seguintes funções retornam cursores diretamente:
Collection.find()
Collection.aggregate()
Collection.listIndexes()
Collection.listSearchIndexes()
Db.aggregate()
Db.listCollections()
Outros métodos, como Collection.findOne() e Collection.watch() use cursores internamente e retorne os resultados das operações em vez de um cursor.
Paradigmas de cursor
Você pode trabalhar com cursores usando vários paradigmas de cursor. A maioria dos paradigmas de cursor permite acessar os resultados da query um documento de cada vez, abstraindo a lógica de rede e de cache. No entanto, como os casos de uso são diferentes, outros paradigmas oferecem padrões de acesso diferentes, como a extração de todos os documentos correspondentes para uma coleção na memória do processo.
Aviso
Não combine diferentes paradigmas de cursor em um único cursor. Operações como hasNext()
e toArray()
modificam previsivelmente o cursor original. Se você misturar essas chamadas
em um único cursor, poderá receber resultados inesperados.
Aviso
Como as chamadas assíncronas modificam diretamente o cursor, a execução simultânea de chamadas assíncronas em um único cursor também pode causar comportamento indefinido. Aguarde sempre que a operação assíncrona anterior seja concluída antes de executar outra.
Observação
Quando você atinge o último resultado através da iteração ou através de uma busca única, o cursor se esgota, o que significa que ele deixa de responder aos métodos que acessam os resultados.
iteração assíncrona
Os cursores implementam a interface AsyncIterator, que permite usar cursores em for await...of
loops:
const cursor = myColl.find({}); console.log("async"); for await (const doc of cursor) { console.log(doc); }
Iteração manual
Você pode usar o método hasNext() para verificar se um cursor pode fornecer dados adicionais e, em seguida, usar o método next() para recuperar o elemento subsequente do cursor:
const cursor = myColl.find({}); while (await cursor.hasNext()) { console.log(await cursor.next()); }
Retornar uma bandeja de todos os documentos
Para casos de uso que exigem que todos os documentos correspondidos por uma query sejam mantidos na memória ao mesmo tempo, use o método toArray(). Observe que um grande número de documentos correspondentes pode causar problemas de desempenho ou falhas se a operação exceder as restrições de memória. Considere usar a sintaxe for await...of
para iterar os resultados em vez de retornar todos os documentos de uma só vez.
const cursor = myColl.find({}); const allValues = await cursor.toArray();
API de transmissão
Os cursores expõem o método stream()
para convertê-los em fluxos legíveis de nó. Esses fluxos operam no Modo de Objeto, que passa objetos JavaScript em vez de Buffers ou Strings pelo pipeline.
const cursor = myColl.find({}); cursor.stream().on("data", doc => console.log(doc));
API de eventos
Como fluxos legíveis, os cursores também suportam os eventos close
, data
, end
e readable
da API de eventos:
const cursor = myColl.find({}); // the "data" event is fired once per document cursor.on("data", data => console.log(data));
Métodos de Utilidade do Cursor
Retroceder
Para redefinir um cursor para sua posição inicial no conjunto de documentos retornados, use rewind().
const cursor = myColl.find({}); const firstResult = await cursor.toArray(); console.log("First count: " + firstResult.length); await cursor.rewind(); const secondResult = await cursor.toArray(); console.log("Second count: " + secondResult.length);
Fechar
Os cursores consomem memória e recursos de rede tanto no aplicativo cliente quanto na instância conectada do MongoDB. Use close() para liberar os recursos de um cursor no aplicativo cliente e no servidor MongoDB:
await cursor.close();