Iterar um cursor em mongosh
Nesta página
O método db.collection.find()
retorna um cursor. Para acessar os documentos, você precisa iterar o cursor. No entanto, em mongosh
, se o cursor retornado não for atribuído a uma variável usando a palavra-chave var
, o cursor será automaticamente iterado até 20 vezes [1] para imprimir até os primeiros 20 documentos nos resultados.
Os exemplos a seguir descrevem maneiras de iterar manualmente o cursor para acessar os documentos ou usar o índice do iterador.
Iteração manual do cursor
Em mongosh
, quando você atribui o cursor retornado do método find()
a uma variável usando a palavra-chave var
, o cursor não itera automaticamente.
Você pode chamar a variável do cursor no shell para iterar até 20 vezes [1] e imprimir os documentos correspondentes, como no exemplo a seguir:
var myCursor = db.users.find( { type: 2 } ); myCursor
Você também pode usar o método do cursor next()
para acessar os documentos, como no exemplo a seguir:
var myCursor = db.users.find( { type: 2 } ); while (myCursor.hasNext()) { print(tojson(myCursor.next())); }
Como uma operação de impressão alternativa, considere o método de ajuda do printjson()
para substituir o print(tojson())
:
var myCursor = db.users.find( { type: 2 } ); while (myCursor.hasNext()) { printjson(myCursor.next()); }
Você pode usar o método de cursor forEach()
para iterar o cursor e acessar os documentos, como no exemplo a seguir:
var myCursor = db.users.find( { type: 2 } ); myCursor.forEach(printjson);
Consulte os métodos de cursor JavaScript e a documentação do driver para obter mais informações sobre os métodos de cursor.
[1] | (1, 2) Você pode definir o atributo DBQuery.shellBatchSize para alterar o número de documentos do valor padrão de 20 . |
Índice do Iterador
No mongosh
, você pode utilizar o método toArray()
para iterar o cursor e retornar os documentos em um array, assim:
var myCursor = db.inventory.find( { type: 2 } ); var documentArray = myCursor.toArray(); var myDocument = documentArray[3];
O método toArray()
carrega na RAM todos os documentos retornados pelo cursor; O método toArray()
esgota o cursor.
Além disso, alguns drivers fornecem acesso aos documentos usando um índice no cursor (ou seja, cursor[index]
). Esse é um atalho para chamar primeiro o método toArray()
e depois usar um índice na matriz resultante.
Considere o seguinte exemplo:
var myCursor = db.users.find( { type: 2 } ); var myDocument = myCursor[1];
myCursor[1]
é equivalente ao seguinte exemplo:
myCursor.toArray() [1];
Comportamentos do cursor
Cursores abertos dentro de uma sessão
A partir do MongoDB 5.0, os cursores criados em uma sessão de cliente são fechados nas seguintes situações: quando a sessão de servidor correspondente termina com o comando killSessions
, se a sessão atingir o tempo limite ou se o cliente tiver esgotado o cursor.
Por padrão, as sessões do servidor têm um tempo limite de expiração de 30 minutos. Para alterar o valor, defina o parâmetro localLogicalSessionTimeoutMinutes
ao iniciar mongod
.
Cursores abertos fora de uma sessão
Os cursores que não são abertos em uma sessão fecham automaticamente após 10 minutos de inatividade ou se o cliente tiver esgotado o cursor. Para substituir esse comportamento em mongosh
, você pode usar o método cursor.noCursorTimeout()
:
var myCursor = db.users.find().noCursorTimeout();
Após definir a opção noCursorTimeout
, você deve fechar o cursor manualmente com cursor.close()
ou esgotando os resultados do cursor.
Consulte a documentação do driver para obter informações sobre como definir a opção noCursorTimeout
.
Isolamento do cursor
À medida que um cursor retorna documentos, outras operações podem intercalar-se com a query.
Lotes de cursores
O servidor MongoDB retorna os resultados da query em lotes. A quantidade de dados no lote não excederá o tamanho máximo do documento JSON. Para substituir o tamanho padrão do lote, consulte batchSize()
e limit()
.
Operações do tipo find()
, aggregate()
, listIndexes
e listCollections
retornam no máximo 16 megabytes por lote. batchSize()
pode forçar um limite menor, mas não maior.
find()
e aggregate()
operações têm um tamanho de lote inicial de 101 documentos por padrão. As operações subsequentes getMore
emitidas contra o cursor resultante não têm tamanho de lote padrão, portanto, são limitadas apenas pelo tamanho da mensagem de 16 megabytes.
Para consultas que incluem uma operação de classificação sem índice, o servidor deve carregar todos os documentos na memória para executar a classificação antes de retornar quaisquer resultados.
À medida que você itera pelo cursor e chega ao final do lote retornado, se houver mais resultados, cursor.next()
executará um getMore operation
para recuperar o próximo lote. Para ver quantos documentos permanecem no lote à medida que você itera o cursor, você pode usar o método objsLeftInBatch()
, como no exemplo a seguir:
var myCursor = db.inventory.find(); var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null; myCursor.objsLeftInBatch();
Resultados do cursor para bancos de mongos
dados inexistentes
A partir do MongoDB 7.2, as query do aggregation pipeline que tentam usar reconhecimento de data center inexistentes em implantações do mongos retornam erros de validação.
Nas versões anteriores, essas query de agregação retornam cursor vazios.
Informações do cursor
O método db.serverStatus()
retorna um documento que inclui um campo metrics
. O campo metrics
contém um campo metrics.cursor
com as seguintes informações:
número de cursores com tempo limite desde a última reinicialização do servidor
número de cursores abertos com a opção
DBQuery.Option.noTimeout
definida para evitar o tempo limite após um período de inatividadenúmero de cursores abertos "pinned"
número total de cursores abertos
Considere o exemplo a seguir, que chama o método db.serverStatus()
e acessa o campo metrics
dos resultados e, em seguida, o campo cursor
do campo metrics
:
db.serverStatus().metrics.cursor
O resultado é o seguinte documento:
{ "timedOut" : <number> "open" : { "noTimeout" : <number>, "pinned" : <number>, "total" : <number> } }