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

Trabajar con datos BSON

En esta guía, puede aprender cómo funciona el controlador Rust de MongoDB y el bson Esta biblioteca permite representar datos BSON, convertir entre tipos BSON y Rust, y trabajar con documentos BSON directamente en el código de su aplicación.

El controlador utiliza la biblioteca bson para codificar y decodificar datos BSON y utiliza el marco Serde para serializar y deserializar sus tipos Rust. Para obtener más información sobre la serialización, consulte la Guíade modelado y serialización de datos.

Para obtener más información sobre BSON y la lista completa de tipos BSON, consulte BSON types en el manual del MongoDB Server.

Los ejemplos de esta guía utilizan el siguiente documento de muestra, que representa un restaurante llamado "Mongo's Pizza" con un documento de dirección y coordenadas incrustados:

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",
};

MongoDB almacena los documentos en una representación binaria llamada BSON (JSON binario). BSON admite todos los tipos de estructuras de datos JSON y añade tipos adicionales como fechas, enteros de diferentes tamaños, valores ObjectId, datos binarios y más.

En el ecosistema de Rust, el crate bson modela valores BSON usando la enumeración bson::Bson y documentos BSON usando la estructura bson::Document.

Tip

No es necesario agregar bson como dependencia directa si ya está utilizando la biblioteca mongodb. El controlador reexporta bson, por lo que puede importarlo desde su aplicación sin una entrada separada en su archivo Cargo.toml.

La biblioteca bson proporciona los siguientes tipos y macros básicos para trabajar con datos BSON:

  • bson::Bson: Enumeración que representa cualquier valor BSON, como cadena, entero, documento o matriz.

  • bson::Document: Mapa ordenado de claves de cadena UTF-8 a valores Bson que representan un documento BSON.

  • bson! macro: Construye un valor Bson a partir de un literal.

  • doc! macro: Construye un Document a partir de un literal.

Por ejemplo, puede utilizar la doc! macro para construir el restaurant documento de ejemplo que se muestra al comienzo de esta guía.

Puedes acceder a los campos en un Document ya sea como valores Bson sin tipo o como valores Rust fuertemente tipados mediante el uso de métodos auxiliares, como se muestra en el siguiente ejemplo:

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

Puedes modificar el contenido de un Document utilizando operaciones estándar similares a las de un mapa, como la inserción, el reemplazo y la eliminación, como se muestra en el siguiente ejemplo:

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());
}

En lugar de trabajar directamente con valores Document, puedes modelar los datos de tu colección con tipos Rust personalizados. El controlador y la biblioteca bson se integran con Serde para serializar tus tipos a BSON y deserializar BSON de nuevo a tus tipos. Para usar un tipo personalizado como parámetro genérico de un mongodb::Collection, deriva los rasgos serde::Serialize y serde::Deserialize en tu estructura.

El siguiente ejemplo define una estructura Restaurant que incluye los campos name, cuisine y last_updated, parametriza una colección utilizando esta estructura y, a continuación, construye e inserta un documento Restaurant con la marca de tiempo actual 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(())
}

Cuando se parametriza una colección mediante un tipo personalizado, el controlador serializa automáticamente el tipo a BSON al escribir y deserializa BSON de nuevo al tipo al leer.

La biblioteca bson proporciona tipos de Rust que representan tipos de valores BSON, como ObjectId y DateTime, que implementan Serialize y Deserialize. Puedes integrar estos tipos directamente en tus estructuras de dominio para controlar cómo se serializan y deserializan los campos desde BSON.

El siguiente ejemplo define una estructura Order que utiliza el tipo ObjectId para el campo _id y el tipo DateTime para el campo delivery_date, asegurando que estos campos se almacenen y recuperen como sus tipos BSON correspondientes:

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

Para obtener opciones de personalización adicionales, como cambiar el nombre de los campos, omitir campos y cómo usar las funciones auxiliares, consulte la guía de modelado y serialización de datos.

Los bson modelos de la caja representan valores UUID con el Uuidtipo, que corresponde a un valor binario BSON con subtipo 0x04 (UUID). Con las banderas de características apropiadas, también puede integrarse con el uuid crate a través del módulo bson::uuid.

Puede incrustar valores UUID directamente en sus tipos de dominio, como se muestra en el siguiente ejemplo:

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

Debido a que el controlador y bson se integran con Serde, los valores UUID se serializan automáticamente como UUID binarios BSON y se deserializan de nuevo al tipo Rust apropiado.

Para cargas de trabajo que requieren un alto rendimiento, es posible que desee inspeccionar o validar documentos BSON sin deserializarlos completamente en estructuras Rust fuertemente tipadas. La biblioteca bson expone los siguientes tipos sin procesar para este propósito:

  • RawDocument - Fragmento prestado de un documento BSON, similar a str

  • RawDocumentBuf - Documento BSON propio, similar a String

  • RawBsonRef: referencia prestada a un único valor BSON sin procesar.

Puedes crear un RawDocumentBuf a partir de una porción de bytes o un Vec<u8> y luego buscar campos por clave, como se muestra en el siguiente ejemplo:

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(())
}

Estas API sin procesar permiten acceder a campos específicos y validar la estructura del documento sin asignar ni deserializar documentos completos en tipos Rust de nivel superior.

Puedes serializar un Document o cualquier tipo serializable por Serde a su representación en formato BSON y escribirlo en disco. La bson biblioteca proporciona el método Document::to_vec() para codificar un documento a su representación en bytes BSON.

El siguiente ejemplo escribe el documento de muestra del restaurante en un archivo:

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 leer datos BSON desde un archivo, puede cargar los bytes sin procesar y luego decodificarlos en un tipo Document u otro tipo serializable por Serde. La biblioteca bson admite la lectura de documentos directamente desde un búfer o lector en memoria.

El siguiente ejemplo lee un documento BSON desde el disco y lo imprime como JSON extendido para su depuración:

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(())
}

Las funciones auxiliares de codificación y decodificación del paquete bson están diseñadas para interactuar con los controladores de MongoDB y otras bibliotecas BSON, de modo que pueda utilizar la misma representación BSON tanto en disco como a través de la red.

Para obtener más información sobre los tipos y métodos descritos en esta guía, consulte la siguiente documentación:

Volver

intercalación

En esta página