FAQ
在此页面上
在此页面上,您可以找到常见问题解答。
提示
如果在此页面上找不到问题的回答,请参阅问题和帮助页面,了解如何报告问题。
为什么在连接 MongoDB 时出现错误?
如果在连接到 MongoDB 部署时出现问题,请参阅连接故障排除指南,了解潜在的解决方案。
连接池化在 Rust 驱动程序中是如何工作的?
MongoDB 集群中的每个服务器都维护一个连接池。 您可以使用 客户端 的实例来访问权限或管理连接池的行为。连接池按需打开套接字以支持多线程应用程序中的并发操作。
您可以配置以下连接池功能:
最大和最小大小,由
max_pool_size
和min_pool_size
选项设置池并行创建的最大连接数,由
max_connecting
选项设置最大空闲时间,由
max_idle_time
选项设置
有关连接池化的更多信息,请参阅《性能注意事项》指南中的“连接池”部分。
如何在 BSON 和 Rust 类型之间转换?
Rust 驱动程序和 BSON 库使用 Serde 框架执行自定义 Rust 类型和 BSON 之间的转换。 您可以将serde
crate 添加到Cargo.toml
文件中,以访问 Serde 框架的功能。 有关添加此板条箱的说明,请参阅 serde 在 crates 注册表中。
将 crate 添加到应用程序后,您可以使用自定义类型而不是 BSON 文档对collection中的文档进行建模。以下示例在Vegetable
结构定义之前包含derive
属性,该属性指示驱动程序在需要时执行以下操作:
序列化结构体,将结构体转换为 BSON
反序列化 BSON,将 BSON 数据转换为结构体
struct Vegetable { // Add struct fields here }
然后,您可以创建一个Collection
实例,将自定义结构类型作为其泛型类型参数。 以下示例将使用Vegetable
类型参数化的Collection
实例分配给my_coll
变量:
let my_coll: Collection<Vegetable> = client.database("db").collection("vegetables");
有关 BSON 和 Rust 类型之间转换的更多信息,请参阅《数据建模和序列化》指南以及 MongoDB 开发者中心文章《 Rust 中使用 Serde 构建数据》。
如何修复未满足特征边界错误?
特征边界允许方法限制它们接受作为参数的类型以及这些类型必须实现的功能。 例如,如果您定义一个接受泛型类型参数并打印其值的方法,则该参数必须实现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
如果满足T
的特征边界,则Cursor<T>
类型仅实现访问try_next()
方法所需的Stream
特征。 也就是说,T
必须实现DeserializeOwned
特征,如 游标 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
包提供派生宏来生成某些特征的实现,包括Deserialize
特征。 但是,此板条箱不提供DeserializeOwned
特征的派生宏。 实现Deserialize
而没有生命周期限制的数据类型会自动实现DeserializeOwned
,因此您可以实现Deserialize
来满足DeserializeOwned
特征边界。
以下示例调整Actor
结构体定义以实施Deserialize
:
struct Actor { name: String, }
有关特征边界的更多信息,请参阅以下资源:
如何处理结果或选项枚举中包装的值?
Rust 提供Result
和Option
枚举作为应用程序代码的保护措施。 Rust 驱动程序提供的许多方法都会返回以这两种类型之一包装的值。
Result
枚举可以返回以下变体:
Ok(T)
:封装操作结果的值Err(E)
:如果操作不成功,则会封装一个错误值
例如, insert_one()
方法返回Result
类型以包装成功响应或错误。
要访问insert_one()
的解包结果,请使用?
操作符。 如果操作成功,该方法将返回Result
枚举的Ok(InsertOneResult)
变体。 在本例中, ?
操作符会解包InsertOneResult
值并将其赋值给insert_one_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
语法来处理None
和Some(T)
变体。 或者,您可以使用if let
语法仅处理Some(T)
变体。 以下代码将打开并打印非空read_concern()
返回值(如果存在):
if let Some(rc) = my_coll.read_concern() { println!("Read concern: {:?}", rc); }
有关Result
和Option
枚举的更多信息,请参阅 Rust 语言文档中的以下资源: