Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
Menu Docs

Acessar dados usando um cursor

Neste guia, você aprenderá a usar o driver Rust para acessar os dados retornados de uma operação de leitura ou agregação usando um cursor . Um cursor é um mecanismo que permite iterar vários documentos enquanto mantém apenas um subconjunto deles na memória em determinado momento.

O driver oferece o tipo Cursor para recuperar documentos de um cursor. Por exemplo, quando você executa uma operação de busca que pode retornar vários documentos, o driver retorna uma instância do Cursor da qual você pode acessar os documentos correspondentes.

Após executar uma operação de leitura ou agregação, a instância do Cursor retornada contém o primeiro lote de resultados da operação. À medida que você itera pelo cursor, o servidor retorna mais resultados individuais. Se houver mais documentos correspondentes depois que você chegar ao final de um lote de resultados, a instância Cursor buscará o próximo lote de documentos até que todos os resultados sejam retornados.

Este guia inclui as seguintes seções:

Os exemplos deste guia usam os seguintes dados armazenados em uma estrutura:

let docs = vec! [
Fruit {
name: "strawberry".to_string(),
color: "red".to_string()
},
Fruit {
name: "banana".to_string(),
color: "yellow".to_string()
},
Fruit {
name: "pomegranate".to_string(),
color: "red".to_string()
},
Fruit {
name: "pineapple".to_string(),
color: "yellow".to_string()
}
];

O driver fornece os seguintes padrões de acesso para iterar por meio de documentos retornados por uma instância Cursor :

As seções a seguir descrevem esses padrões de acesso e métodos correspondentes em mais detalhes.

Você pode usar o padrão de acesso integrado do driver para recuperar e processar documentos um a um.

O tipo Cursor inclui os métodos advance() e deserialize_current() para iterar por meio de um cursor e acessar documentos individualmente.

O método advance() move o cursor para a frente e envia uma solicitação ao reconhecimento de data center para mais resultados quando o buffer local se esgota, o que ocorre quando o cursor atinge o final de um lote de resultados. Cada vez que o cursor chega ao final de um lote de resultados, ele solicita o próximo lote. O cursor fica esgotado quando não tem mais documentos correspondentes para retornar e não pode mais ser usado. O método advance() retorna um resultado true se os novos resultados forem retornados com êxito e um resultado false se o cursor estiver fechado.

O método deserialize_current() retorna uma referência ao resultado atual no cursor e desserializa o resultado no tipo associado ao cursor. A menos que você especifique um tipo, o método usa o mesmo tipo com o qual sua coleção é parametrizada.

Importante

Você pode chamar o método deserialize_current() somente se o método advance() retornar um resultado true . O driver gera um erro se você chamar deserialize_current() no cursor sem um resultado true ou sem chamar anteriormente advance().

O exemplo a seguir mostra como implementar esse padrão de acesso para iterar os resultados de uma operação de localizar na coleção fruits :

let mut cursor = my_coll.find(doc! { "color": "red" }, None).await?;
while cursor.advance().await? {
println!("{:?}", cursor.deserialize_current()?);
}
Fruit { name: "strawberry", color: "red" }
Fruit { name: "pomegranate", color: "red" }

Você pode acessar os resultados do cursor como um fluxo para recuperar documentos individuais ou coletar vários documentos de uma só vez.

O tipo Cursor implementa a Stream , para que você possa iterar por meio de um cursor como um fluxo. Você pode usar esse padrão para escrever um código mais conciso do que com o padrão integrado, pois a extensão Stream StreamExt fornece inúmeras funções para combinar operações e confirmar código.

Você pode usar os seguintes métodos para usar o padrão de fluxo:

  • next(): avança o cursor para o próximo resultado e retorna um tipo Option<Result<T>>

  • try_next(): avança o cursor para o próximo resultado e retorna um tipo Result<Option<T>>

Importante

Importações necessárias para métodos de padrão de stream

Para usar o método next() , você deve importar o traço StreamExt . Para usar o método try_next() , você deve importar o traço TryStreamExt .

O exemplo a seguir mostra como implementar os dois métodos de fluxo para iterar os resultados das operações de localização na collection fruits :

let mut cursor = my_coll.find(doc! { "color": "red" }, None).await?;
println!("Output from next() iteration:");
while let Some(doc) = cursor.next().await {
println!("{:?}", doc?);
}
println!();
let mut cursor = my_coll.find(doc! { "color": "yellow" }, None).await?;
println!("Output from try_next() iteration:");
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Output from next() iteration:
Fruit { name: "strawberry", color: "red" }
Fruit { name: "pomegranate", color: "red" }
Output from try_next() iteration:
Fruit { name: "banana", color: "yellow" }
Fruit { name: "pineapple", color: "yellow" }

Como o tipo Cursor implementa a Stream , você pode coletar os resultados de um cursor em uma array.

Você pode usar os seguintes métodos para recuperar documentos como um array:

  • collect(): coleta resultados de um cursor em um tipo Vec<Result<T>>

  • try_collect(): coleta resultados de um cursor em um tipo Result<Vec<T>>

Observação

Para usar o método collect() , você deve importar o traço StreamExt . Para usar o método try_collect() , você deve importar o traço TryStreamExt .

let cursor = my_coll.find(doc! { "color": "red" }, None).await?;
println!("Output from collect():");
let v: Vec<Result<Fruit>> = cursor.collect().await;
println!("{:?}", v);
println!();
let cursor = my_coll.find(doc! { "color": "yellow" }, None).await?;
println!("Output from try_collect():");
let v: Vec<Fruit> = cursor.try_collect().await?;
println!("{:?}", v);
Output from collect():
[Ok(Fruit { name: "strawberry", color: "red" }), Ok(Fruit { name: "pomegranate", color: "red" })]
Output from try_collect():
[Fruit { name: "banana", color: "yellow" }, Fruit { name: "pineapple", color: "yellow" }]

Aviso

Evite exceder os limites de memória do aplicativo

Evite converter grandes conjuntos de resultados em arrays. Se a array exceder o tamanho da memória disponível do aplicação , seu aplicação poderá falhar. Se você espera um conjunto de resultados grande, recupere os documentos do cursor individualmente. Para saber como fazer a iteração por meio do cursor, consulte a seção Recuperar documentos individualmente deste guia.

Para modificar o cursor que uma operação retorna, passe opções para o método que retorna a instância Cursor . Por exemplo, você pode especificar opções relacionadas ao cursor em um tipo FindOptions que você passa para o método find() .

Observação

Opções de Instanciação

O driver Rust implementa o padrão de design Builder para a criação de muitos tipos diferentes, incluindo FindOptions. Você pode usar o método builder() de cada tipo para construir uma instância de opções encadeando as funções do construtor de opções, uma de cada vez.

A tabela a seguir descreve as opções relacionadas ao cursor que você pode definir em uma instância de opções:

Contexto
Descrição

batch_size

Especifica o número máximo de documentos que o servidor retorna por lote de cursor. Essa opção define o número de documentos que o cursor mantém na memória, em vez do número de documentos que o cursor retorna.

Tipo: u32
Padrão: 101 documentos inicialmente, 16 MB máximo para lotes subsequentes

cursor_type

Especifica o tipo de cursor a ser retornado. Você pode definir esta opção para produzir um cursor persistente. Para saber mais sobre cursores persistentes, consulte Cursores persistentes no manual do servidor.

Tipo: CursorType
Padrão: CursorType::NonTailable

no_cursor_timeout

Especifica se o servidor fecha o cursor após um período de inatividade.

IMPORTANTE: Como o tipo Cursor implementa a característica Drop, o servidor fecha um cursor quando ele sai do escopo. O servidor executa um comando assíncrono killCursors para fechar o cursor. Consulte killCursors no manual do servidor para aprender mais.

Tipo: bool
Padrão: false

O seguinte código mostra como construir uma instância do FindOptions e especificar as configurações relacionadas ao cursor:

let opts: FindOptions = FindOptions::builder()
.batch_size(5)
.cursor_type(CursorType::Tailable)
.no_cursor_timeout(true)
.build();

Para saber mais sobre as operações neste guia, consulte a seguinte documentação:

Para saber mais sobre a conversão entre tipos de Rust e BSON, consulte o guia sobre modelagem de dados e serialização.

Para saber mais sobre os métodos e tipos mencionados neste guia, consulte a documentação da API abaixo: