Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /

Modelado y serialización de datos

En esta guía, puedes aprender sobre cómo el driver Rust gestiona las conversiones entre BSON y los tipos de 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 conversiones entre tipos Rust y BSON, el driver y el BSON la caja integra funcionalidad del marco Serde.

Tip

La bson la caja se exporta con la caja mongodb. Para aprender a instalar la serde caja, consulta serde en el registro de cajas de crates.io.

Implementando la funcionalidad de la caja serde en tu aplicación, puedes utilizar tipos Rust personalizados, como structs y enums (estructuras y enumeraciones) para modelar tus datos.

Esta guía incluye las siguientes secciones:

  • Parámetro Genérico de Tipo describe la parametrización de colecciones y el modelado de datos

  • Modelo de datos personalizado describe cómo definir tipos de Rust personalizados para modelar datos en tus colecciones.

  • Serialización personalizada describe cómo modificar el comportamiento por defecto de serialización y deserialización utilizando atributos y proporciona ejemplos

  • Información adicional proporciona enlaces a recursos y documentación de la API para los tipos y métodos mencionados en esta guía

Al crear una instancia de Collection, debe especificar un parámetro de tipo genérico para representar el tipo de datos que modelan los documentos de su colección. Para aprender más sobre cómo especificar un parámetro de tipo genérico, consulta Sección de parametrización de la colección de la guía sobre Bases de datos y colecciones.

Recomendamos definir y usar un tipo personalizado para modelar los datos de la colección en lugar de usar el tipo Document.

Puedes usar cualquier tipo de dato Rust que implemente los traits Serialize y Deserialize de la caja serde como parámetro de tipo genérico para una instancia de Collection. Para implementar los Serialize y Deserialize, debes incluir el siguiente derive atributo antes de definir un tipo de Rust:

#[derive(Serialize, Deserialize)]

El siguiente código define una muestra de Article struct que implementa los rasgos de serialización de serde:

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

Tip

Tipo de Vector

A partir de la librería bson v2.14, puedes 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 de almacenamiento. Para obtener más información, consulta la especificación de 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");

Debido a que la instancia Collection está parametrizada con el struct Article, puedes 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 tu colección contiene varios esquemas, puedes definir un tipo personalizado para modelar cada tipo de dato y crear clones de la instancia original de Collection para cada tipo. Puedes crear clones de una instancia de Collection usando el método clone_with_type().

Supongamos que inicialmente parametrizaste una colección con una estructura denominada Square, pero luego te das cuenta de que deseas insertar un tipo diferente de datos, modelado por la estructura Circle, en la colección. El siguiente código parametriza una colección con el tipo Square, luego crea un clon de la colección que está 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 utilizando atributos de la caja serde. Los atributos son elementos opcionales de metadatos adjuntos a los campos de las estructuras o variantes de enumeraciones.

La serde caja proporciona los atributos serialize_with y deserialize_with, que toman funciones asistentes como valores. Estas funciones auxiliares personalizan la serialización y deserialización de 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, se encuentran ejemplos que utilizan tipos auxiliares de la librería bson para realizar tareas comunes de serialización.

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 2.x: Utiliza las funciones asistentes tradicionales serialize_with

BSON 2.15 es la versión por defecto. Elige el enfoque que coincida con tu versión de la caja BSON.

Para utilizar BSON 3.0 en tu aplicación, actívalo como una funcionalidad en el Cargo.toml de tu proyecto, similar a lo siguiente:

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

Al activar BSON 3.0, puedes usar serde_as. Para usar serde_as, debes importarlo en tu aplicación, como se muestra en el siguiente código:

use serde_with::serde_as;

Para ver una lista completa de funciones asistentes de Serde, consulta la documentación de la API serde_helpers.

Podrías querer 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 ejemplos de código correspondientes dependiendo de tu versión de la caja BSON:

Utiliza 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,
}

Usa la función asistente 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 Order de ejemplo en BSON, seleccione 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"
}

Es posible que desees representar un valor de campo DateTime en un documento como una string con formato ISO en BSON. Selecciona la pestaña BSON 3.0(serde_as) o BSON 2.x (serialize_with) para ejemplos de código correspondientes a esta conversión.

Utiliza 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,
}

Usa la función asistente 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 a 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"
}

Puede que quieras representar un valor de campo u32 en un documento como un f64 o Double tipo en BSON. Selecciona la pestaña BSON 3.0(serde_as) o BSON 2.x (serialize_with) para ver los ejemplos de código correspondientes que especifican esta conversión.

Utiliza 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,
}

Usa la función asistente 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 aparece igual que el valor original.

Además de las funciones auxiliares, la librería bson provee módulos que gestionan tanto la serialización como la deserialización. Para seleccionar un módulo para usar en un campo o variante específica, define el valor del atributo with con el nombre del módulo:

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

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

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

  • renameserializar y deserializar un campo con un nombre especificado en lugar del nombre de la struct o variante de Rust

  • skip: no serializar o deserializar el campo especificado

  • defaultSi no hay un valor presente durante la deserialización, usa el valor por defecto de Default::default()

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

Para más información sobre los BSON types, consulta BSON types en el manual del servidor.

Para ver más ejemplos que demuestren la funcionalidad de serde, consulta el artículo Estructuración de datos con Serde en Rust en el Centro de desarrollo.

Para aprender más sobre el marco Serde, consulta la documentación de Serde.

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

Volver

BSON

En esta página