在此页面上,您可以找到常见问题解答。
提示
如果在此页面上找不到问题的回答,请参阅问题和帮助页面,了解如何报告问题。
为什么在连接 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。
将 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 特征,如 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包提供派生宏来生成某些特征的实现,包括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 语言文档中的以下资源: