Visão geral
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 .
Amostra de documento BSON
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", };
Tipos de dados JSON
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.
Representar BSON no Rust
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 valorBsona partir de um literal.doc!macro: Constrói umDocumenta 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
Modificar um documento BSON
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()); }
Use tipos de Rust para modelar documentos BSON
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:
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.
Personalizar comportamento de serialização
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:
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 .
Trabalhar com Valores UUID
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 :
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.
Use dados BSON brutos
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
strRawDocumentBuf - documento BSON de propriedade, semelhante a
StringRawBsonRef - 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.
Grave BSON em um arquivo
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) }
Leia BSON de um arquivo
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.
Recursos adicionais
Para saber mais sobre os tipos e métodos descritos neste guia, consulte a seguinte documentação:
Documentação da API bson crate
Bsonpara,,Documenttipos brutos, UUIDs e auxiliares de JSON estendidoTipos de JSON no manual do MongoDB Server