Docs Menu
Docs Home
/ /

Modelado y serialización de datos

En esta guía, aprenderá cómo el controlador de Rust gestiona las conversiones entre tipos BSON y Rust. El proceso de convertir un tipo de Rust a BSON se denomina serialización, mientras que el proceso inverso se denomina deserialización.

El lenguaje Rust utiliza un sistema de tipos estático, pero BSON tiene un esquema dinámico. Para gestionar las conversiones entre los tipos de Rust y BSON, el controlador y el... BSONLa caja integra funcionalidades del marco Serde.

Tip

El bson El cajón se exporta con el mongodb cajón. Para saber cómo instalar el serde cajón,consulte serde en el crates.io registro del cajón.

Al implementar la funcionalidad del paquete serde en su aplicación, puede usar tipos de Rust personalizados, como estructuras y enumeraciones, para modelar sus datos.

Esta guía incluye las siguientes secciones:

Al crear una instancia Collection, debe especificar un parámetro de tipo genérico para representar el tipo de datos que modela los documentos de su colección. Para obtener más información sobre cómo especificar un parámetro de tipo genérico, consulte Sección de Parametrización de Colecciones de la guía sobre Bases de Datos y Colecciones.

Le recomendamos que defina y utilice un tipo personalizado para modelar los datos de su colección en lugar de utilizar el tipo Document.

Puede usar cualquier tipo de datos de Rust que implemente los atributos Serialize y Deserialize del paquete serde como parámetro de tipo genérico para una instancia Collection. Para implementar los atributos Serialize y Deserialize, debe incluir el siguiente atributo derive antes de definir un tipo de Rust:

#[derive(Serialize, Deserialize)]

El siguiente código define una estructura Article de muestra que implementa las características de serialización serde:

#[derive(Serialize, Deserialize)]
struct Article {
title: String,
date: DateTime,
content: String,
content_embeddings: Vector,
}

Tip

Tipo de vector

A partir de la bson biblioteca v,2.14 puede utilizar el tipo bson::binary::Vector para representar vectores de valores numéricos.

Dado que este tipo se serializa como un vector binario BSON, el uso de Vector puede mejorar la eficiencia del almacenamiento. Para obtener más información, consulte la especificación BSON.

El siguiente código accede a la colección articles con la estructura Article como su parámetro de tipo genérico:

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

Dado que la instancia Collection está parametrizada con la estructura Article, se pueden realizar operaciones CRUD con este tipo. El siguiente código inserta una instancia Article en la colección:

let article = Article {
title: "Maintaining Your Garden in Winter".to_string(),
date: DateTime::now(),
content: "As fall winds down, you might be wondering what you should be doing in your garden in the coming months ...".to_string(),
content_embeddings: Vector::Float32(vec! [0.01020927,-0.011224265,0.015686288,-0.018586276,-0.023160344])
};
my_coll.insert_one(article).await?;

Si su colección contiene varios esquemas, puede definir un tipo personalizado para modelar cada tipo de dato y crear clones de la instancia Collection original para cada tipo. Puede crear clones de una instancia Collection mediante el método clone_with_type().

Supongamos que inicialmente parametrizó una colección con una estructura llamada Square, pero posteriormente se da cuenta de que desea insertar en ella un tipo de datos diferente, modelado por la estructura Circle. El siguiente código parametriza una colección con el tipo Square y luego crea un clon de la colección parametrizada con el tipo Circle:

let shapes_coll: Collection<Square> = client
.database("db")
.collection("shapes");
// ... perform some operations with Square
let shapes_coll: Collection<Circle> = shapes_coll.clone_with_type();
// ... perform some operations with Circle

Puedes modificar el comportamiento predeterminado de serialización y deserialización del controlador de Rust mediante atributos del serde paquete. Los atributos son metadatos opcionales que se adjuntan a campos de estructuras o variantes de enumeraciones.

El contenedor serde proporciona los atributos serialize_with y deserialize_with, que toman funciones auxiliares como valores. Estas funciones auxiliares personalizan la serialización y deserialización en campos y variantes específicos. Para especificar un atributo en un campo, incluya el atributo antes de la definición del campo:

#[derive(Serialize, Deserialize)]
struct MyStruct {
#[serde(serialize_with = "<helper function>")]
field1: String,
// ... other fields
}

En las siguientes secciones, puede encontrar ejemplos que utilizan tipos auxiliares de la biblioteca bson para lograr tareas de serialización comunes.

Los ejemplos muestran los siguientes enfoques:

  • BSON 3.0: Utiliza la anotación serde_as proporcionada por la caja serde_with, que ofrece mayor flexibilidad y capacidades de composición.

  • BSON.x:2 utiliza las serialize_with funciones auxiliares tradicionales

BSON 2.15 es la versión predeterminada. Elija el enfoque que coincida con la versión de su contenedor BSON.

Para utilizar BSON 3.0 en su aplicación, habilítelo como una característica en el Cargo.toml de su proyecto, de manera similar a lo siguiente:

[dependencies.mongodb]
version = "3.3.0"
features = ["bson-3"]

Al habilitar BSON 3.0, puede usar serde_as. Para usar serde_as, debe importarlo en su aplicación, como se muestra en el siguiente código:

use serde_with::serde_as;

Para ver una lista completa de las funciones auxiliares de Serde, consulte la documentación de la API serde_helpers.

Quizás quieras representar el campo _id en un documento como una cadena hexadecimal en tu estructura. Para convertir la cadena hexadecimal al tipo BSON ObjectId, selecciona el BSON 3.0 (serde_as) o la pestaña BSON 2.x (serialize_with) para ver ejemplos de código correspondientes según la versión de su caja BSON:

Utilice el tipo bson::serde_helpers::object_id::FromHexString con la anotación serde_as:

#[serde_as]
#[derive(Serialize, Deserialize)]
struct Order {
#[serde_as(as = "object_id::FromHexString")]
_id: String,
item: String,
}

Utilice la función auxiliar serialize_hex_string_as_object_id:

#[derive(Serialize, Deserialize)]
struct Order {
#[serde(serialize_with = "serialize_hex_string_as_object_id")]
_id: String,
item: String,
}

Para ver cómo el controlador serializa una estructura de muestra Order en BSON, seleccione una de las siguientes pestañas Struct y BSON:

let order = Order {
_id: "6348acd2e1a47ca32e79f46f".to_string(),
item: "lima beans".to_string(),
};
{
"_id": { "$oid": "6348acd2e1a47ca32e79f46f" },
"item": "lima beans"
}

Quizás desee representar un valor de campo DateTime en un documento como una cadena con formato ISO en BSON. Seleccione la pestaña BSON 3.0(serde_as) o BSON 2.x (serialize_with) para ver los ejemplos de código correspondientes a esta conversión.

Utilice el tipo bson::serde_helpers::datetime::AsRfc3339String con la anotación serde_as:

#[serde_as]
#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde_as(as = "datetime::AsRfc3339String")]
delivery_date: DateTime,
}

Utilice la función auxiliar serialize_bson_datetime_as_rfc3339_string:

#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde(serialize_with = "serialize_bson_datetime_as_rfc3339_string")]
delivery_date: DateTime,
}

Seleccione la pestaña BSON 3.0(serde_as) o BSON 2.x (serialize_with) para ver cómo el controlador serializa una estructura de muestra Order en BSON.

let order = Order {
item: "lima beans".to_string(),
delivery_date: DateTime::now(),
};
{
"_id": { ... },
"item": "lima beans",
"delivery_date": "2023-09-26T17:30:18.181Z"
}

Es posible que desee representar un valor de campo u32 en un documento como un tipo f64 o Double en BSON. Seleccione la pestaña BSON 3.0(serde_as) o BSON 2.x (serialize_with) para ver los ejemplos de código correspondientes y especificar esta conversión.

Utilice el tipo bson::serde_helpers::u32::AsF64 con la anotación serde_as:

#[serde_as]
#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde_as(as = "u32::AsF64")]
quantity: u32,
}

Utilice la función auxiliar serialize_u32_as_f64:

#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde(serialize_with = "serialize_u32_as_f64")]
quantity: u32,
}

Nota

La representación BSON Double de un valor u32 parece la misma que el valor original.

Además de las funciones auxiliares, la biblioteca bson proporciona módulos que gestionan tanto la serialización como la deserialización. Para seleccionar un módulo para un campo o variante específicos, asigne el valor del atributo with al nombre del módulo:

#[derive(Serialize, Deserialize)]
struct MyStruct {
#[serde(with = "<module>")]
field1: u32,
// ... other fields
}

Para obtener una lista completa de estos módulos, consulte la documentación de la API serde_helpers.

El contenedor serde proporciona muchos otros atributos para personalizar la serialización. La siguiente lista describe algunos atributos comunes y su funcionalidad:

  • rename: serializar y deserializar un campo con un nombre especificado en lugar del nombre de la estructura o variante de Rust

  • skip: no serializar ni deserializar el campo especificado

  • default: si no hay ningún valor presente durante la deserialización, utilice el valor predeterminado de Default::default()

Para una lista completa de atributos de serde, consulta la Documentación API de atributos serde.

Para obtener más información sobre los tipos BSON, consulte Tipos BSON en el manual del servidor.

Para obtener más ejemplos que demuestran serde la funcionalidad, consulte el artículo Estructuración de datos con Serde en el Centro para desarrolladores de Rust.

Para obtener más información sobre el marco Serde, consulte la documentación de Serde.

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

Volver

Tutorial: Aplicación web CRUD

En esta página