Overview
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.
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:
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.
La serialización personalizada describe cómo modificar el comportamiento de serialización y deserialización predeterminado mediante el uso de 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
Parámetro de tipo genérico
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.
Recomendamos definir y usar un tipo personalizado para modelar los datos de la colección en lugar de usar el tipo Document.
Modelo de datos personalizado
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:
Ejemplo de Struct personalizado
El siguiente código define una estructura Article de muestra que implementa las características de serialización serde:
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?;
Parametrizaciones múltiples
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 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
Serialización personalizada
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:
struct MyStruct { 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_asproporcionada por la cajaserde_with, que ofrece mayor flexibilidad y capacidades de composición.BSON.x:2 utiliza las
serialize_withfunciones 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 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 las funciones auxiliares de Serde, consulte la documentación de la API serde_helpers.
Serializar un String como un ObjectId
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 ver ejemplos de código correspondientes según la versión de su caja BSON:
Utiliza el tipo bson::serde_helpers::object_id::FromHexString con la anotación serde_as:
struct Order { _id: String, item: String, }
Usa la función asistente serialize_hex_string_as_object_id:
struct Order { _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" }
Serializar un DateTime como una string
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:
struct Order { item: String, delivery_date: DateTime, }
Usa la función asistente serialize_bson_datetime_as_rfc3339_string:
struct Order { item: 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" }
Serializar un u32 como f64
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:
struct Order { item: String, quantity: u32, }
Usa la función asistente serialize_u32_as_f64:
struct Order { item: String, quantity: u32, }
Nota
La representación BSON Double de un valor u32 aparece igual que el valor original.
Otros atributos y módulos
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:
struct MyStruct { 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 Rustskip: no serializar ni deserializar el campo especificadodefault: si no hay ningún valor presente durante la deserialización, utilice el valor predeterminado deDefault::default()
Para una lista completa de atributos de serde, consulta la Documentación API de atributos serde.
Información Adicional
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.
Documentación de la API
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:
serialize_with atributo Serde
deserializar_con atributo Serde
con Atributo Serde