文档菜单
文档首页
/ / /
Rust 驱动
/

数据建模与序列化

本页内容

  • 概述
  • 泛型类型参数
  • 自定义数据模型
  • 自定义结构体示例
  • 多参数化
  • 自定义序列化
  • 将字符串序列化为 ObjectId
  • 将日期时间序列化为字符串
  • 将 u32 序列化为 f64
  • 其他属性和模块
  • 更多信息
  • API 文档

在这份指南中,您可以了解Rust驱动程序如何处理BSON和Rust类型之间的转换。将Rust类型转换为BSON的过程称为序列化,而反向过程称为反序列化

Rust语言使用静态类型系统,但BSON具有动态模式。为了处理Rust类型和BSON之间的转换,驱动程序和bson库集成了Serde框架的功能。有关如何安装serdecrate的信息,请参阅serdecrates.iocrate注册表。

通过将serdecrate的功能实现到您的应用程序中,您可以使用自定义Rust类型,如结构和枚举来建模您的数据。

本指南包括以下部分

  • 泛型类型参数描述了集合参数化和数据建模

  • 自定义数据模型描述了如何定义自定义Rust类型来对集合中的数据进行建模

  • 自定义序列化描述了如何通过使用属性来修改默认的序列化和反序列化行为,并提供示例

  • 附加信息提供了本指南中提到的类型和方法的相关资源链接和API文档

当您创建一个 Collection 实例时,您必须指定一个泛型类型参数来表示您的集合中文档的数据类型。有关指定泛型类型参数的更多信息,请参阅集合参数化部分的数据库和集合指南。

我们建议您定义并使用一个自定义类型来表示您的集合数据,而不是使用 Document 类型。

您可以使用任何实现了 SerializeDeserialize 特性的 serde 包中的 Rust 数据类型作为 Collection 实例的泛型类型参数。要实现 SerializeDeserialize 特性,您必须在定义 Rust 类型之前包含以下 derive 属性

#[derive(Serialize, Deserialize)]

以下代码定义了一个示例 Vegetable 结构,该结构实现了 serde 序列化特性

#[derive(Serialize, Deserialize)]
struct Vegetable {
name: String,
category: String,
tropical: bool,
}

以下代码使用 Vegetable 作为其泛型类型参数访问 vegetables 集合

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

因为Collection实例使用Vegetable结构体进行了参数化,所以可以使用该类型执行CRUD操作。以下代码将一个Vegetable实例插入到集合中

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的结构体参数化了一个集合,但后来你意识到你想要将不同类型的数据(由Circle结构体建模)插入到集合中。以下代码使用Square类型参数化了一个集合,然后创建了一个使用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

您可以使用serde crate中的serialize_withdeserialize_with属性来修改Rust驱动程序的默认序列化和反序列化行为。属性是附加到结构体字段或枚举变体的可选元数据。

serde crate提供了serialize_withdeserialize_with属性,它们接受辅助函数作为值。这些辅助函数自定义特定字段和变体的序列化和反序列化。要在字段上指定属性,在字段定义之前包含该属性

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

在下文中,您可以找到使用 bson 库中的辅助函数实现常见序列化任务的示例。要查看这些辅助函数的完整列表,请参阅 serde_helpers API 文档。

您可能希望在结构体中将文档的 _id 字段表示为十六进制字符串。要将十六进制字符串转换为 ObjectId BSON 类型,请使用 serialize_hex_string_as_object_id 辅助函数作为 serialize_with 属性的值。以下示例将 serialize_with 属性附加到 _id 字段,以便驱动程序将十六进制字符串序列化为 ObjectId 类型

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

要了解驱动程序如何将示例 Order 结构体序列化为 BSON,请从以下选项中选择结构体BSON 选项卡

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

您可能想在文档中将 DateTime 字段值表示为 ISO 格式的字符串,在 BSON 中。为了指定这种转换,请使用 serialize_bson_datetime_as_rfc3339_string 辅助函数作为附加到具有 DateTime 值的字段的 serialize_with 属性的值。以下示例将 serialize_with 属性附加到 delivery_date 字段,以便驱动程序将 DateTime 值序列化为字符串。

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

要查看驱动程序如何将示例 Order 结构序列化为 BSON,请从以下 结构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 字段值表示为 BSON 中的 f64Double 类型。为了指定这种转换,请使用 serialize_u32_as_f64 辅助函数作为附加到具有 u32 值的字段的 serialize_with 属性的值。以下示例将 serialize_with 属性附加到 quantity 字段,以便驱动程序将 u32 值序列化为 Double 类型。

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

注意

u32 值的 BSON Double 表示形式与原始值相同。

除了辅助函数之外,bson 库还提供了处理序列化和反序列化的模块。要为特定字段或变体选择要使用的模块,请将 with 属性的值设置为模块名称

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

有关这些模块的完整列表,请参阅 serde_helpers API 文档。

serde 包提供了许多其他属性来自定义序列化。以下列表描述了一些常见的属性及其功能

  • rename:使用指定的名称而不是 Rust 结构体或变体名称进行序列化和反序列化字段

  • skip:不序列化或反序列化指定的字段

  • default:如果在反序列化过程中不存在值,则使用 Default::default() 的默认值

关于serde属性的完整列表,请参阅serde 属性 API 文档。

要了解更多关于 BSON 类型的信息,请参阅服务器手册中的BSON 类型

有关演示 serde 功能的更多示例,请参阅开发者中心文章使用 Serde 在 Rust 中结构化数据

要了解更多关于 Serde 框架的信息,请参阅Serde 文档。

要了解更多关于本指南中提到的方法和类型,请参阅以下 API 文档

返回

复合操作