数据建模和序列化
在此页面上
Overview
在本指南中,您可以了解 Rust 驱动程序如何处理 BSON 和 Rust 类型之间的转换。 将 Rust 类型转换为 BSON 的过程称为序列化,而相反的过程称为反序列化。
Rust语言使用静态类型系统,但BSON具有动态模式。 为了处理Rust类型和BSON之间的转换,驾驶员和 bson
库集成了 Serde框架的功能。要学习;了解如何安装serde
crate,请参阅 crates.io
crate 注册表中的 Serde 。
通过将 serde
库的功能整合到您的应用程序中,您可以使用自定义 Rust 类型(如结构体和枚举)来对数据进行建模。
本指南包括以下部分:
泛型类型参数
创建Collection
实例时,必须指定泛型类型参数来表示对集合中的文档进行建模的数据类型。 要学习;了解有关指定泛型类型参数的更多信息,请参阅数据库和集合指南中的集合参数化部分。
我们建议您定义并使用自定义类型来对集合的数据进行建模,而不是使用Document
类型。
自定义数据模型
您可以使用任何实现serde
包中的Serialize
和Deserialize
特征的 Rust 数据类型作为Collection
实例的泛型类型参数。 要实现Serialize
和Deserialize
特征,您必须在定义 Rust 类型之前包含以下derive
属性:
自定义结构示例
以下代码定义了一个示例Vegetable
结构,用于实现serde
序列化特征:
struct Vegetable { name: String, category: String, tropical: bool, }
以下代码访问将Vegetable
作为泛型类型参数的vegetables
集合:
let my_coll: Collection<Vegetable> = client .database("db") .collection("vegetables");
由于Collection
实例已使用Vegetable
结构进行参数化,因此您可以使用该类型执行 CRUD 操作。 Vegetable
以下代码将一个实例插入到collection中:
let calabash = Vegetable { name: "calabash".to_string(), category: "gourd".to_string(), tropical: true, }; my_coll.insert_one(calabash).await?;
多个参数化
如果您的集合包含多个模式,则可以定义自定义类型来对每种数据类型进行建模,并为每种类型创建原始Collection
实例的克隆。 您可以使用clone_with_type()
方法创建Collection
实例的克隆。
假设您最初使用名为Square
的结构体参数化了一个collection,但您后来意识到想要将由Circle
结构体建模的不同类型的数据插入到该collection中。以下代码将Square
类型的collection参数化,然后创建Circle
类型参数化的collection的克隆:
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
自定义序列化
您可以使用serde
crate 中的属性修改 Rust 驱动程序的默认序列化和反序列化行为。 属性是附加到字段的结构体或枚举变体的可选元数据片段。
serde
包提供serialize_with
和deserialize_with
属性,它们将辅助函数作为值。 这些辅助函数可自定义特定字段和变体的序列化和反序列化。 要在字段上指定属性,请在字段定义之前包含该属性:
struct MyStruct { field1: String, // ... other fields }
在以下部分中,您可以找到使用bson
库中的辅助函数实现常见序列化任务的示例。 要查看这些辅助函数的完整列表,请参阅 serde_helpers API 文档。
将字符串序列化为 ObjectId
您可能希望将文档中的_id
字段表示为结构体中的十六进制字符串。 要将十六进制字符串转换为ObjectId
BSON 类型,请使用serialize_hex_string_as_object_id
辅助函数作为serialize_with
属性的值。 以下示例将serialize_with
属性附加到_id
字段,以便驱动程序将十六进制字符串序列化为ObjectId
类型:
struct Order { _id: String, item: String, }
要查看驱动程序如何将示例Order
结构序列化为 BSON,请从以下 Struct和BSON标签页中进行选择:
let order = Order { _id: "6348acd2e1a47ca32e79f46f".to_string(), item: "lima beans".to_string(), };
{ "_id": { "$oid": "6348acd2e1a47ca32e79f46f" }, "item": "lima beans" }
将 DateTime 序列化为字符串
您可能希望将文档中的DateTime
字段值表示为 BSON 中的 ISO 格式的字符串。 要指定此转换,请使用serialize_bson_datetime_as_rfc3339_string
辅助函数作为附加到具有DateTime
值的字段的serialize_with
属性的值。 以下示例将serialize_with
属性附加到delivery_date
字段,以便驱动程序将DateTime
值序列化为字符串:
struct Order { item: String, delivery_date: DateTime, }
要查看驱动程序如何将示例Order
结构序列化为 BSON,请从以下Struct和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" }
将 u32 序列化为 f64
您可能希望将文档中的u32
字段值表示为 BSON 中的f64
或Double
类型。 要指定此转换,请使用serialize_u32_as_f64
辅助函数作为附加到具有u32
值的字段的serialize_with
属性的值。 以下示例将serialize_with
属性附加到quantity
字段,以便驱动程序将u32
值序列化为Double
类型:
struct Order { item: String, quantity: u32, }
注意
u32
值的 BSON Double
表示形式与原始值相同。
其他属性和模块
除辅助函数外, bson
库还提供处理序列化和反序列化的模块。 要选择用于特定字段或变体的模块,请将with
属性的值设置为模块的名称:
struct MyStruct { field1: u32, // ... other fields }
有关这些模块的完整列表,请参阅 serde_helpers API 文档。
serde
库提供了许多其他属性来自定义序列化。以下列表描述了一些常见属性及其功能:
rename
:使用指定名称而不是 Rust 结构或变体名称对字段进行序列化和反序列化skip
:不对指定字段进行序列化或反序列化default
:如果反序列化期间不存在任何值,则使用以下内容中的默认值:Default::default()
有关serde
属性的完整列表,请参阅 serde 属性 API 文档。
更多信息
要了解有关BSON types 的更多信息,请参阅BSON types MongoDB Server手册中的 。
有关演示serde
功能的更多示例,请参阅Rust 开发者中心的《使用 Serde 构建数据》一文。
要了解有关 Serde 框架的更多信息,请参阅 Serde 文档。
API 文档
要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档:
Serialize_with Serde 属性
deserialize_with Serde 属性
与 Serde 属性