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

常见问题解答

本页内容

  • 为什么我在连接 MongoDB 时会出错?
  • Rust 驱动中的连接池是如何工作的?
  • 我如何将 BSON 和 Rust 类型之间进行转换?
  • 我如何修复未满足的特质界限错误?
  • 我如何处理包装在 Result 或 Option 枚举中的值?

在本页中,您可以找到常见问题及其相应答案。

提示

如果您在本页上找不到问题的答案,请参阅问题与帮助页面,了解如何报告问题。

如果你在连接MongoDB部署时遇到麻烦,请参阅连接故障排除指南以获取可能的解决方案。

你的MongoDB集群中的每个服务器都维护一个连接池。你可以通过一个实例来访问或管理连接池的行为Client。连接池会在需要时打开套接字以支持多线程应用程序中的并发操作。

你可以配置以下连接池功能

  • 最大和最小大小,通过max_pool_sizemin_pool_size选项设置

  • 池创建的并发连接的最大数量,通过max_connecting选项设置

  • 最大空闲时间,通过max_idle_time选项设置

有关连接池的更多信息,请参阅性能注意事项指南中的连接池部分。

Rust驱动程序和BSON库使用Serde框架在自定义Rust类型和BSON之间执行转换。您可以将serdecrate添加到您的Cargo.toml文件中,以访问Serde框架的功能。有关添加此crate的说明,请参阅crates注册表中的serde

将crate添加到您的应用程序后,您可以使用自定义类型而不是BSON文档来建模集合中的文档。以下示例在Vegetable结构定义之前包含derive属性,这指示驱动程序在需要时执行以下操作

  • 序列化结构,将结构转换为BSON

  • 反序列化BSON,将BSON数据转换为您的结构

#[derive(Serialize, Deserialize)]
struct Vegetable {
// Add struct fields here
}

然后,您可以使用自定义结构类型作为其泛型类型参数创建一个Collection实例。以下示例将参数化为Vegetable类型的Collection实例分配给变量my_coll

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

有关BSON和Rust类型之间转换的更多信息,请参阅数据建模和序列化指南以及MongoDB开发者中心的使用Serde在Rust中结构化数据文章。

特征边界允许方法限制它们接受哪些类型的参数以及这些类型必须实现哪些功能。例如,如果你定义了一个接受泛型类型参数并打印其值的函数,则该参数必须实现用于打印的 Display 特征。以下示例定义了 printer() 函数并指定其参数必须实现 Display

fn printer<T: Display>(t: T) {
println!("{}", t);
}

在调用数据类型的函数时,你可能遇到一个错误,表明该函数的特征边界没有得到满足。例如,当你在 Cursor 实例上调用 try_next() 函数时,驱动程序可能会引发以下错误消息

error[E0599]: the method `try_next` exists for struct `mongodb::Cursor<T>`,
but its trait bounds were not satisfied

Cursor<T> 类型仅实现了 Stream 特征,这是访问 try_next() 函数所必需的。如果 T 的特征边界得到满足,则需要。也就是说,T 必须实现 DeserializeOwned 特征,如Cursor API 文档所述。以下示例通过定义自定义的 Actor 结构来模拟 actors 集合中的文档。但是,此结构没有实现 DeserializeOwned 特征,并使用 try_next() 方法遍历 Actor 实例会导致错误

struct Actor {
name: String,
}
// Add setup code here
let my_coll: Collection<Actor> = client.database("db").collection("actors");
let mut cursor = my_coll.find(doc! {}).await?;
while let Some(result) = cursor.try_next().await? {
println!("{:?}", result);
};

要解决特征边界错误,请确定游标迭代的类型,并确保该类型实现了 DeserializeOwned 特征。你可以使用 derive 属性来应用所需的特征边界。

注意

Deserialize 和 DeserializeOwned 特征

《serde》库提供了一个 derive 宏,用于生成某些特质的实现,包括 Deserialize 特质。然而,这个库并没有为 DeserializeOwned 特质提供 derive 宏。数据类型在实现 Deserialize 时,如果没有生命周期限制,则会自动实现 DeserializeOwned,因此你可以实现 Deserialize 来满足 DeserializeOwned 特质约束。

以下示例调整了 Actor 结构体的定义以实现 Deserialize

#[derive(Deserialize)]
struct Actor {
name: String,
}

有关特质约束的更多信息,请参阅以下资源

Rust提供了ResultOption枚举作为应用程序代码的保护。Rust驱动程序提供的许多方法返回值被包裹在这两种类型之一中。

Result枚举可以返回以下变体

  • Ok(T):封装操作的结果值

  • Err(E):在操作失败时封装错误值

例如,insert_one()方法返回一个Result类型,以封装成功响应或错误。

要访问insert_one()的未封装结果,请使用?运算符。如果操作成功,该方法返回Result枚举的Ok(InsertOneResult)变体。在这种情况下,?运算符解包InsertOneResult值并将其分配给insert_one_result变量。如果操作失败,该方法返回Result枚举的Err(E)变体,并且?运算符解包并返回错误值。以下代码演示了在处理插入操作结果时使用?运算符的语法

let insert_one_result = my_coll.insert_one(doc).await?;

或者,您可以创建一个条件来处理InsertOneResult的未封装值。以下代码使用match关键字处理insert_one()结果

let insert_one_result = my_coll.insert_one(doc).await;
match insert_one_result {
Ok(val) => {
println!("Document inserted with ID: {}", val.inserted_id);
},
Err(err) => {
println!("Operation not successful");
}
}

Option枚举可以返回以下变体

  • None:表示由操作返回的空值

  • Some(T):封装非空返回值

一些Rust驱动程序方法返回Option类型,例如read_concern()方法。该方法返回一个Option,它封装了空值(如果不存在读取关注),或者ReadConcern值。

要访问read_concern()的结果,您可以使用与前面示例中相同的match语法来处理NoneSome(T)变体。或者,您可以使用if let语法来处理仅Some(T)变体。以下代码解包并打印非空的read_concern()返回值,如果存在的话

if let Some(rc) = my_coll.read_concern() {
println!("Read concern: {:?}", rc);
}

有关ResultOption枚举的更多信息,请参阅Rust语言文档中的以下资源

返回

GridFS