Menu Docs
Página inicial do Docs
/ / /
Driver Rust

Perguntas frequentes

Nesta página

  • Por que obtenho erros ao conectar ao MongoDB?
  • Como funciona o pool de conexões no driver Rust?
  • Como faço para converter entre os tipos de BSON e Rust?
  • Como faço para corrigir erros de limites de características insatisfatórios?
  • Como faço para processar um valor envolto em um resultado ou opção enumeração?

Nesta página, você pode encontrar perguntas frequentes e suas respostas correspondentes.

Dica

Se você não conseguir encontrar uma resposta para sua pergunta nesta página, consulte a página Problemas e ajuda para obter informações sobre como relatar problemas.

Se você tiver problemas para se conectar a uma implantação do MongoDB, consulte o Guia de Solução de Problemas de Conexão para obter possíveis soluções.

Cada servidor no cluster MongoDB mantém um pool de conexões. Você pode acessar ou gerenciar o comportamento do pool de conexões usando uma instância de um cliente. Os pools de conexões abrem soquetes sob demanda para oferecer suporte a operações simultâneas em seu aplicação de threads múltiplas.

Você pode configurar os seguintes recursos do pool de conexões:

  • Tamanho máximo e mínimo, definido pelas opções max_pool_size e min_pool_size

  • Número máximo de conexões que o grupo cria em paralelo, definido pela opção max_connecting

  • Tempo máximo ocioso, definido pela opção max_idle_time

Para obter mais informações sobre o pool de conexões, consulte a seção Pool de conexões do guia Considerações de Desempenho.

O driver Rust e a biblioteca BSON usam a estrutura Serde para executar conversões entre tipos Rust personalizados e BSON. Você pode adicionar a caixa serde ao seu arquivo Cargo.toml para acessar a funcionalidade da estrutura Serde. Para obter instruções sobre como adicionar esta caixa,consulte serde no registro de caixas.

Depois de adicionar a caixa ao seu aplicativo, você pode modelar os documentos em uma coleção usando um tipo personalizado em vez de um documento BSON. O exemplo seguinte inclui o atributo derive antes da definição de estrutura Vegetable , que instrui o driver a executar a seguinte ação quando necessário:

  • Serialize a estrutura, que converte a estrutura em BSON

  • Deserialize o BSON, que converte dados BSON em sua estrutura

#[derive(Serialize, Deserialize)]
struct Vegetable {
// Add struct fields here
}

Você pode então criar uma instância Collection com seu tipo de estrutura personalizado como parâmetro de tipo genérico. O exemplo seguinte atribui uma instância Collection parametrizada com o tipo Vegetable à variável my_coll :

let my_coll: Collection<Vegetable> = client.database("db").collection("vegetables");

Para obter mais informações sobre a conversão entre os tipos BSON e Rust, consulte o guia Modelagem e serialização de dados e o artigo Structuring Data with Serde in Rust MongoDB Developer Center.

Os limites de características permitem que os métodos restrinjam quais tipos eles aceitam como parâmetros e qual funcionalidade esses tipos devem implementar. Por exemplo, se você definir um método que aceita um parâmetro de tipo genérico e imprime seu valor, o parâmetro deverá implementar a Display para fins de impressão. O exemplo a seguir define o método printer() e especifica que seu parâmetro deve implementar Display:

fn printer<T: Display>(t: T) {
println!("{}", t);
}

Ao chamar um método em um tipo de dados, você pode encontrar um erro informando que os limites da propriedade do método não estão satisfeitos. Por exemplo, o driver pode gerar a seguinte mensagem de erro quando você chama o método try_next() em uma instância Cursor :

error[E0599]: the method `try_next` exists for struct `mongodb::Cursor<T>`,
but its trait bounds were not satisfied

O tipo Cursor<T> só implementa o traço Stream , que é necessário para acessar o método try_next() , se os limites do traço para T estiverem satisfeitos. Ou seja, T deve implementar a DeserializeOwned traça , conforme especificado no Cursor Documentação da API. O exemplo a seguir replica a mensagem de erro anterior definindo uma estrutura Actor personalizada para modelar documentos na coleção actors . No entanto, essa estrutura não implementa a funcionalidade DeserializeOwned , e usar o método try_next() para iterar sobre instâncias Actor causa um erro:

struct Actor {
name: String,
}
// Add setup code here
let my_coll: Collection<Actor> = client.database("db").collection("actors");
let mut cursor = my_coll.find(doc! {}).await?;
while let Some(result) = cursor.try_next().await? {
println!("{:?}", result);
};

Para resolver o erro de limites de transação, identifique o tipo de dados sobre o qual o cursor itera e certifique-se de que esse tipo de dados implemente a DeserializeOwned . Você pode utilizar o atributo derive para aplicar o limite de traço exigido.

Observação

Deserializar e desserializar características próprias

A caixa serde fornece macros derivadas para gerar a implementação de determinadas características, incluindo a Deserialize . No entanto, esta caixa não oferece uma macro de derivação para a DeserializeOwned . Os tipos de dados que implementam Deserialize sem restrições de vida útil implementam automaticamente DeserializeOwned, portanto, você pode implementar Deserialize para preencher o limite de características DeserializeOwned .

O exemplo a seguir ajusta a definição de estrutura Actor para implementar Deserialize:

#[derive(Deserialize)]
struct Actor {
name: String,
}

Para obter mais informações sobre limites de características, consulte os seguintes recursos:

O Rust fornece os enums Result e Option como proteção para o código do seu aplicativo. Muitos métodos oferecidos pelo driver Rust retornam valores envoltos em um desses dois tipos.

A enumeração Result pode retornar as seguintes variantes:

  • Ok(T): envolve o valor do resultado da operação

  • Err(E): envolve um valor de erro se a operação não for bem-sucedida

Por exemplo, o método insert_one() retorna um tipo Result para envolver uma resposta bem-sucedida ou um erro.

Para acessar o resultado não agrupado de insert_one(), use o operador ? . Se a operação for bem-sucedida, o método retornará a Ok(InsertOneResult) variante da Result enumeração . Nesse caso, o operador ? desenrola o valor InsertOneResult e o atribui à variável insert_one_result . Se a operação não for bem-sucedida, o método retornará a variante da enumeração Err(E) e o operador ? desembrulhará e retornará o valor de erro. O seguinte código demonstra a sintaxe para utilizar o operador ? ao lidar com um resultado de operação de inserção:

let insert_one_result = my_coll.insert_one(doc).await?;

Alternativamente, você pode criar um condicional para lidar com os valores não agrupados de InsertOneResult. O código a seguir usa a palavra-chave match para processar o resultado insert_one() :

let insert_one_result = my_coll.insert_one(doc).await;
match insert_one_result {
Ok(val) => {
println!("Document inserted with ID: {}", val.inserted_id);
},
Err(err) => {
println!("Operation not successful");
}
}

A enumeração Option pode retornar as seguintes variantes:

  • None: representa um valor vazio retornado por uma operação

  • Some(T): envolve um valor de retorno não vazio

Alguns métodos de driver Rust retornam um tipo de Option , como o método read_concern() . Este método retorna um Option que envolve um valor vazio, se não existir nenhuma referência de leitura, ou um valor ReadConcern .

Para acessar o resultado de read_concern(), você pode usar a mesma sintaxe match mostrada no exemplo anterior para processar as variantes None e Some(T) . Como alternativa, você pode usar a sintaxe if let para processar somente a variante Some(T) . O seguinte código desembrulha e imprime o valor de retorno read_concern() não vazio, se existir:

if let Some(rc) = my_coll.read_concern() {
println!("Read concern: {:?}", rc);
}

Para obter mais informações sobre os enums Result e Option , consulte os seguintes recursos na documentação da linguagem Rust:

Voltar

GridFS