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()
.
Novidades na versão 3.4: Operações do tipo find()
, aggregate()
, listIndexes
e listCollections
retornam um máximo de 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();
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> } }