Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Menu Docs
Página inicial do Docs
/ /

Trabalhe com Dados BSON

Neste guia, você aprenderá como o Driver Rust do MongoDB e a crate bson representam dados BSON, convertem entre os tipos BSON e Rust e trabalham com documentos BSON diretamente no código do seu aplicação .

O driver usa a bson crate para codificar e decodificar dados BSON e usa a estrutura Serde para serializar e desserializar seus tipos de Rust. Para saber mais sobre serialização, consulte o guia Modelagem de dados e serialização.

Para obter mais informações sobre BSON e a lista completa de tipos de BSON, consulte Tipos de BSON no manual do MongoDB Server .

Os exemplos deste guia usam o seguinte documento de amostra , que representa um restaurante chamado "Mongo's Pizza" com um documento de endereço e coordenadas incorporados:

let mut restaurant: Document = doc! {
"address": {
"street": "Pizza St",
"zipcode": "10003",
},
"coord": [-73.982_419_f64, 41.579_505_f64],
"cuisine": "Pizza",
"name": "Mongo's Pizza",
};

O MongoDB armazena documentos em uma representação binária chamada BSON (Binary JSON). O BSON é compatível com todos os tipos de estrutura de dados JSON e adiciona tipos adicionais, como datas, inteiros de tamanhos diferentes, valores ObjectId, dados binários e muito mais.

No ecossistema Rust, a crate bson modela valores BSON usando o enumeração bson::Bson e documentos BSON usando a estrutura bson::Document .

Dica

Você não precisa adicionar bson como uma dependência direta se já estiver usando a crate mongodb. O driver reexporta bson, para que você possa importá-lo do seu aplicação sem uma entrada separada no arquivo Cargo.toml.

A crate bson fornece os seguintes tipos principais e macros para trabalhar com dados BSON:

  • bson::Bson: Enum que representa qualquer valor BSON, como string, inteiro, documento ou array.

  • bson::Document: Mapa ordenado das chaves de string UTF-8 para valores BSON que representa um documento BSON.

  • bson! macro: Constrói um valor Bson a partir de um literal.

  • doc! macro: Constrói um Document a partir de um literal.

Por exemplo, você pode usar a doc! macro para construir o restaurant documento de amostra mostrado no início deste guia.

Você pode acessar campos em um Document como valores Bson não digitados ou como valores Rust fortemente digitados usando métodos assistente , conforme mostrado no exemplo a seguir:

let value = restaurant.get("cuisine"); // Option<&Bson>
let name = restaurant.get_str("name")?; // &str
let address = restaurant.get_document("address")?; // &Document
let zipcode = address.get_str("zipcode")?; // &str

Você pode modificar o conteúdo de um Document utilizando operações padrão semelhantes a um mapa, como inserção, substituição e remoção, conforme mostrado no exemplo a seguir:

restaurant = Document = doc! {
"address": {
"street": "Pizza St",
"zipcode": "10003",
},
"coord": [-73.982_419_f64, 41.579_505_f64],
"cuisine": "Pizza",
"name": "Mongo's Pizza",
};
// Adds a new field restaurant_id
restaurant.insert("restaurant_id", Bson::Int32(12345));
// Removes the cuisine field
restaurant.remove("cuisine");
// Updates the name field
if let Some(name) = restaurant.get_mut("name") {
*name = Bson::String("Mongo's Pizza Place".to_string());
}

Em vez de trabalhar diretamente com valores do Document, você pode modelar seus dados de coleta com tipos personalizados do Rust. O driver e a crate bson se integram ao Serde para serializar seus tipos para BSON e desserializar BSON de volta para seus tipos. Para usar um tipo personalizado como parâmetro genérico de um mongodb::Collection, derive as características serde::Serialize e serde::Deserialize em sua estrutura.

O exemplo a seguir define uma estrutura Restaurant que inclui os campos name, cuisine e last_updated, parametriza uma collection usando essa estrutura e, em seguida, constrói e insere um documento Restaurant com o carimbo de data/hora atual como { valor last_updated:

#[derive(Serialize, Deserialize)]
struct Restaurant {
name: String,
cuisine: String,
last_updated: DateTime,
}
async fn use_collection(client: &Client) -> mongodb::error::Result<()> {
let coll: Collection<Restaurant> = client
.database("sample_restaurants")
.collection("restaurants");
let doc = Restaurant {
name: "Mongo's Pizza".to_string(),
cuisine: "Pizza".to_string(),
last_updated: DateTime::now(),
};
coll.insert_one(doc).await?;
Ok(())
}

Quando você parametriza uma coleção usando um tipo personalizado, o driver serializa automaticamente seu tipo para BSON ao escrever e desserializa o BSON de volta para seu tipo durante a leitura.

A crate bson fornece tipos de Rust que representam tipos de valor BSON, como ObjectId e DateTime, que implementam Serialize e Deserialize. Você pode incorporar esses tipos diretamente em suas estruturas de domínio para controlar como os campos são serializados e desserializados do BSON.

O exemplo a seguir define uma estrutura Order que usa o tipo ObjectId para o campo _id e o tipo DateTime para o campo delivery_date , garantindo que esses campos sejam armazenados e recuperados como seus tipos BSON correspondentes:

#[derive(Serialize, Deserialize)]
struct Order {
_id: ObjectId,
item: String,
delivery_date: DateTime,
}

Para opções de personalização adicionais, como renomear campos, ignorar campos e como usar funções de assistente , consulte o guia Modelagem e serialização de dados .

A bson crate modela os valores UUID com o tipo Uuid, que corresponde a um valor binário BSON com subtipo 0x04 (UUID). Com os sinalizadores de recurso apropriados, você também pode integrar-se à uuid crate por meio do módulo bson::uuid.

Você pode incorporar valores UUID diretamente em seus tipos de domínio, como mostrado no exemplo a seguir :

#[derive(Serialize, Deserialize)]
struct Session {
id: Uuid,
user_id: Uuid,
created_at: DateTime,
}

Como o driver e o bson se integram ao Serde, os valores de UUID são serializados automaticamente como UUIDs binários BSON e desserializados de volta para o tipo Rust apropriado.

Para cargas de trabalho sensíveis ao desempenho, convém inspecionar ou validar documentos BSON sem desserializá-los totalmente em estruturas Rust fortemente digitadas. A crate bson expõe os seguintes tipos brutos para esse propósito:

  • RawDocument - fatia embarcada de um documento BSON, semelhante a str

  • RawDocumentBuf - documento BSON de propriedade, semelhante a String

  • RawBsonRef - Referência embarcada a um único valor BSON bruto

Você pode criar um RawDocumentBuf a partir de uma fatia de bytes ou Vec<u8> e depois procurar campos por chave, conforme mostrado no exemplo a seguir:

fn inspect_raw(bytes: Vec<u8>) -> Result<(), mongodb::bson::error::Error> {
let raw = RawDocumentBuf::from_bytes(bytes)?;
if let Some(name) = raw.get_str("name").ok() {
println!("Restaurant name: {name}");
}
Ok(())
}

Essas APIs brutas permitem acessar campos específicos e validar a estrutura do documento sem alocar ou desserializar documentos inteiros em tipos Rust de nível superior.

Você pode serializar um Document ou qualquer tipo serializável do Serde para sua representação de formato de fio BSON e escrevê-lo no disco. A bson crate fornece o método Document::to_vec() para codificar um documento para sua representação de bytes BSON.

O exemplo a seguir grava o documento do restaurante de amostra em um arquivo:

fn write_bson_to_file(path: &str) -> std::io::Result<()> {
let restaurant: Document = doc! {
"address": {
"street": "Pizza St",
"zipcode": "10003",
},
"coord": [-73.982_419_f64, 41.579_505_f64],
"cuisine": "Pizza",
"name": "Mongo's Pizza",
};
// Encodes the document as BSON bytes
let bytes = restaurant.to_vec()
.expect("failed to encode document to BSON");
fs::write(path, &bytes)
}

Para ler dados BSON de um arquivo, você pode carregar os bytes brutos e, em seguida, decodificá-los em um Document ou outro tipo serializável Serde. A crate bson suporta a leitura de documentos diretamente de um buffer ou leitor na memória.

O exemplo a seguir lê um documento BSON do disco e o imprime como JSON estendido para depuração:

fn read_bson_from_file(path: &str) -> Result<(), Box<dyn std::error::Error>> {
let bytes = fs::read(path)?;
let mut cursor = Cursor::new(bytes);
// Decodes a single document from the reader
let doc = Document::from_reader(&mut cursor)?;
// Converts to relaxed Extended JSON for logging
let bson_value = Bson::Document(doc);
let json = bson_value.into_relaxed_extjson(); // serde_json::Value
println!("{}", json);
Ok(())
}

Os auxiliares de codificação e decodificação na crate bson são projetados para interoperar com drivers MongoDB e outras bibliotecas BSON, para que você possa usar a mesma representação BSON no disco e na rede.

Para saber mais sobre os tipos e métodos descritos neste guia, consulte a seguinte documentação:

Voltar

Agrupamentos

Nesta página