Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs 菜单
Docs 主页
/ /

使用BSON数据

在本指南中,您可以学习;了解MongoDB Rust驱动程序和 bson crate 如何表示BSON数据、如何在BSON和Rust类型之间进行转换以及直接在应用程序代码中使用BSON文档。

该驾驶员使用bson 包对BSON数据进行编码和解码,并使用 Serde框架对Rust类型进行序列化和反序列化。要学习;了解有关序列化的详情,请参阅 数据建模和序列化指南。

有关BSON 的详细信息以及BSON 类型的完整列表,请参阅MongoDB Server手册中的 BSON类型。

本指南中的示例使用以下示例文档,它表示一家名为“Mongo's Pizza”的餐厅,并带有嵌入式解决文档和坐标:

let mut restaurant: Document = doc! {
"address": {
"street": "Pizza St",
"zipcode": "10003",
},
"coord": [-73.982_419_f64, 41.579_505_f64],
"cuisine": "Pizza",
"name": "Mongo's Pizza",
};

MongoDB以称为BSON (二进制JSON)的二进制表示形式存储文档。 BSON支持所有JSON数据结构类型,并添加了其他类型,例如日期、不同大小的整数、ObjectId 值、二进制数据等。

在Rust生态系统中,bson 包使用 bson::Bson枚举对BSON值进行建模,并使用 bson::Document 结构体对BSON文档进行建模。

提示

如果您已经在使用 mongodb crate,则无需将 bson 添加为直接依赖项。该驾驶员会重新导出 bson,因此您可以从应用程序中将其导入,而无需在 Cargo.toml文件中添加单独的条目。

bson crate 提供以下用于处理BSON数据的核心类型和宏:

  • bson::Bson:表示任何BSON值的枚举,例如字符串、整数、文档或大量。

  • bson::Document:从 UTF-8 字符串键到表示BSON文档的Bson 值的有序映射。

  • bson! 宏:从字面量构造 Bson 值。

  • doc! 宏:从文字构造 Document

示例,您可以使用doc! 宏来构建本指南开头所示的示例restaurant 文档。

您可以使用辅助方法将 Document 中的字段作为非类型化 Bson 值或强类型Rust值访问权限,如以下示例所示:

let value = restaurant.get("cuisine"); // Option<&Bson>
let name = restaurant.get_str("name")?; // &str
let address = restaurant.get_document("address")?; // &Document
let zipcode = address.get_str("zipcode")?; // &str

您可以使用标准的类似映射操作(例如插入、替换和删除)来修改 Document 的内容,如以下示例所示:

restaurant = Document = doc! {
"address": {
"street": "Pizza St",
"zipcode": "10003",
},
"coord": [-73.982_419_f64, 41.579_505_f64],
"cuisine": "Pizza",
"name": "Mongo's Pizza",
};
// Adds a new field restaurant_id
restaurant.insert("restaurant_id", Bson::Int32(12345));
// Removes the cuisine field
restaurant.remove("cuisine");
// Updates the name field
if let Some(name) = restaurant.get_mut("name") {
*name = Bson::String("Mongo's Pizza Place".to_string());
}

您可以使用自定义Rust类型对集合数据进行建模,而不是直接使用 Document 值。驾驶员和 bson 包与 Serde 集成,以将您的类型序列化为BSON并将BSON反序列化回您的类型。要将自定义类型用作 mongodb::Collection 的泛型参数,请在结构体上派生 serde::Serializeserde::Deserialize 特征。

以下示例定义了一个包含 namecuisinelast_updated 字段的 Restaurant 结构体,使用此结构体对集合进行参数化,然后构造并插入一个 Restaurant文档,其中当前时间戳为 last_updated 值:

#[derive(Serialize, Deserialize)]
struct Restaurant {
name: String,
cuisine: String,
last_updated: DateTime,
}
async fn use_collection(client: &Client) -> mongodb::error::Result<()> {
let coll: Collection<Restaurant> = client
.database("sample_restaurants")
.collection("restaurants");
let doc = Restaurant {
name: "Mongo's Pizza".to_string(),
cuisine: "Pizza".to_string(),
last_updated: DateTime::now(),
};
coll.insert_one(doc).await?;
Ok(())
}

使用自定义类型对集合进行参数化时,驾驶员会在写入时自动将您的类型序列化为BSON ,并在读取时将BSON反序列化回您的类型。

bson 包提供表示BSON值类型的Rust类型,例如 ObjectIdDateTime,它们实现了SerializeDeserialize。您可以将这些类型直接嵌入到域结构中,以控制如何将字段序列化为 BSON 和从BSON反序列化。

以下示例定义了一个 Order 结构体,该结构体使用 ObjectId 类型作为 _id字段,使用 DateTime 类型作为 delivery_date字段,确保这些字段作为相应的BSON 类型进行存储和检索:

#[derive(Serialize, Deserialize)]
struct Order {
_id: ObjectId,
item: String,
delivery_date: DateTime,
}

有关其他自定义选项,例如重命名字段、跳过字段以及如何使用辅助函数,请参阅 数据建模和序列化指南。

包使用bson Uuid 类型对 UUID 值进行建模,该类型对应于子类型为0 x04 (UUID) 的BSON二进制值。使用适当的功能标志,您还可以通过uuid bson::uuid 模块与 箱集成。

您可以将 UUID 值直接嵌入到域类型中,如以下示例所示:

#[derive(Serialize, Deserialize)]
struct Session {
id: Uuid,
user_id: Uuid,
created_at: DateTime,
}

由于驾驶员和 bson 与 Serde 集成,因此 UUID 值会自动序列化为BSON二进制 UUID 并反序列化回相应的Rust类型。

对于性能敏感的工作负载,您可能希望检查或验证BSON文档,而不将它们完全反序列化为强类型Rust结构体。 bson 包为此目的公开了以下原始类型:

您可以从字节切片或 Vec<u8> 创建 RawDocumentBuf,然后按键查找字段,如以下示例所示:

fn inspect_raw(bytes: Vec<u8>) -> Result<(), mongodb::bson::error::Error> {
let raw = RawDocumentBuf::from_bytes(bytes)?;
if let Some(name) = raw.get_str("name").ok() {
println!("Restaurant name: {name}");
}
Ok(())
}

这些原始 API 允许您访问权限特定字段并验证文档结构,而无需将整个文档分配或反序列化为更高级别的Rust类型。

您可以将Document 或任何 Serde 可序列化的类型序列化为其BSON传输格式表示形式,并将其写入磁盘。bson 包提供了 Document::to_vec() 方法,用于将文档编码为其BSON字节表示形式。

以下示例将示例餐厅文档写入文件:

fn write_bson_to_file(path: &str) -> std::io::Result<()> {
let restaurant: Document = doc! {
"address": {
"street": "Pizza St",
"zipcode": "10003",
},
"coord": [-73.982_419_f64, 41.579_505_f64],
"cuisine": "Pizza",
"name": "Mongo's Pizza",
};
// Encodes the document as BSON bytes
let bytes = restaurant.to_vec()
.expect("failed to encode document to BSON");
fs::write(path, &bytes)
}

要从文件读取BSON数据,您可以加载原始字节,然后将其解码为 Document 或其他 Serde 可序列化的类型。 bson crate 支持直接从内存缓冲区或读取器读取文档。

以下示例从磁盘读取BSON文档并将其打印为扩展JSON以进行调试:

fn read_bson_from_file(path: &str) -> Result<(), Box<dyn std::error::Error>> {
let bytes = fs::read(path)?;
let mut cursor = Cursor::new(bytes);
// Decodes a single document from the reader
let doc = Document::from_reader(&mut cursor)?;
// Converts to relaxed Extended JSON for logging
let bson_value = Bson::Document(doc);
let json = bson_value.into_relaxed_extjson(); // serde_json::Value
println!("{}", json);
Ok(())
}

bson 包中的编码和解码助手旨在与MongoDB驱动程序和其他BSON库进行互操作,因此您可以在磁盘上和网络上使用相同的BSON表示形式。

要进一步学习;了解本指南中描述的类型和方法,请参阅以下文档:

后退

排序规则(Collations)

在此页面上