Overview
在本指南中,您可以学习如何使用Rust驱动程序执行批量操作。
批量操作针对一个或多个命名空间执行多个写入操作。 命名空间是数据库名称和集合名称的组合,格式为<database>.<collection> 。 由于您对Client实例执行批量操作,因此您可以对客户端访问的集群中的任何命名空间执行批量操作。
您可以执行批量操作以减少对服务器的调用次数。 批量操作不是为每个操作发送请求,而是在一个操作中执行多个动作。
本指南包括以下部分:
样本数据显示批量操作示例使用的示例数据
批量操作类型介绍如何使用
WriteModel类型执行批量插入、替换、更新和删除操作返回类型描述了
bulk_write()方法的返回值以及如何访问权限有关批量操作的信息修改行为描述了如何修改
bulk_write()方法的默认行为写入混合命名空间描述了如何在一次方法调用中对多个命名空间执行批量操作
附加信息提供了本指南中提到的类型和方法的资源和 API 文档链接
重要
要执行批量写入操作,请确保您的应用程序满足以下要求:
您已连接到 MongoDB Server 8.0或更高版本。
您使用的是Rust驱动程序版本 3.0 或更高版本。
样本数据
本指南中的示例使用以下示例文档,这些文档存储在db数据库的mushrooms集合中:
let docs = vec![ doc! {"name" : "portobello", "color" : "brown", "edible" : true }, doc! {"name" : "chanterelle", "color" : "yellow", "edible" : true }, doc! {"name" : "oyster", "color" : "white", "edible" : true }, doc! {"name" : "fly agaric", "color" : "red", "edible" : false }, ];
您还可以使用自定义结构体类型来表示示例数据。 有关使用Mushroom结构体执行批量操作以对相同数据进行建模的示例,请参阅本页上的插入结构体示例。
批量操作类型
要执行批量写入操作,请将WriteModel 枚举实例的大量传递给bulk_write() 方法。
在本节中,您可以学习;了解如何通过定义相应的WriteModel类型来执行以下批量写入操作:
提示
您还可以在一次bulk_write()方法调用中执行多种类型的写入操作。 要查看将UpdateOneModel和InsertOneModel传递给同一bulk_write()调用的示例,请参阅本指南中的修改行为示例。
Insert
要执行批量插入操作,请为要插入的每个文档创建一个InsertOneModel实例。 然后,将模型列表传递给bulk_write()方法。
下表描述了您可以通过调用相应的构建器方法来设立的InsertOneModel字段:
字段 | 说明 |
|---|---|
| 执行插入操作的命名空间空间。类型: |
| 要插入的文档。 |
插入文档示例
此示例将执行以下动作:
在大量中指定两个
InsertOneModel实例。 每个InsertOneModel代表要插入到db.mushrooms命名空间中的文档。将模型大量传递给
bulk_write()方法。打印插入文档的数量。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "lion's mane", "color": "white", "edible": true }) .build(), InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "angel wing", "color": "white", "edible": false }) .build(), ]; let result = client.bulk_write(models).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
插入结构体示例
您还可以使用结构体对文档进行建模,并将结构体实例批量插入db.mushrooms命名空间。
此示例执行与前面的“插入文档示例”相同的操作,但插入以下Mushroom结构类型的实例:
struct Mushroom { name: String, color: String, edible: bool, }
以下代码使用insert_one_model()方法从每个Mushroom实例构造InsertOneModel ,然后在批量操作中插入两个模型:
let mushrooms: Collection<Mushroom> = client.database("db").collection("mushrooms"); let lions_mane = Mushroom { name: "lion's mane".to_string(), color: "white".to_string(), edible: true, }; let angel_wing = Mushroom { name: "angel wing".to_string(), color: "white".to_string(), edible: false, }; let lions_mane_model = mushrooms.insert_one_model(lions_mane)?; let angel_wing_model = mushrooms.insert_one_model(angel_wing)?; let result = client.bulk_write([lions_mane_model, angel_wing_model]).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
提示
要学习有关 Rust 驱动程序中的自定义结构体类型和序列化的更多信息,请参阅数据建模和序列化指南。
替换
要执行批量替换操作,请为每个要替换的文档创建一个ReplaceOneModel实例。 然后,将模型列表传递给bulk_write()方法。
下表描述了您可以通过调用相应的构建器方法来设立的ReplaceOneModel字段:
字段 | 说明 |
|---|---|
| 执行操作的命名空间空间。类型: |
| 与要替换的文档匹配的过滤器。 |
| 替换文档。 |
| |
| |
| (可选)如果没有文档与过滤器匹配,是否创建新文档。 |
例子
此示例将执行以下动作:
在大量中指定两个
ReplaceOneModel实例。ReplaceOneModel实例包含替换db.mushrooms命名空间中表示蘑菇的文档的指令。将模型大量传递给
bulk_write()方法。打印已修改文档的数量。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ ReplaceOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "portobello" }) .replacement(doc! { "name": "cremini", "color": "brown", "edible": true }) .build(), ReplaceOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "oyster" }) .replacement(doc! { "name": "golden oyster", "color": "yellow", "edible": true }) .upsert(true) .build(), ]; let result = client.bulk_write(models).await?; println!("Modified documents: {}", result.modified_count);
Modified documents: 2
Update
要执行批量更新操作,请为要进行的每次更新创建一个UpdateOneModel或UpdateManyModel实例。 然后,将模型列表传递给bulk_write()方法。 UpdateOneModel仅更新与过滤匹配的一个文档,而UpdateManyModel会更新与过滤匹配的所有文档。
下表描述了您可以通过调用相应的构建器方法来设立的UpdateOneModel和UpdateManyModel字段:
字段 | 说明 |
|---|---|
| 执行操作的命名空间空间。类型: |
| 与要更新的一个或多个文档相匹配的过滤器。在 |
| 要执行的更新。 |
| (可选)一设立过滤器,用于指定在更新数组值字段时要对哪些数组元素进行更新。 |
| |
| |
| (可选)如果没有文档与过滤器匹配,是否创建新文档。默认下,此字段设立为 |
例子
此示例将执行以下动作:
在大量中指定一个
UpdateOneModel和一个UpdateManyModel实例。 这些模型包含更新表示db.mushrooms命名空间中蘑菇的文档的指令。将模型大量传递给
bulk_write()方法。打印已修改文档的数量。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::UpdateOne( UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "fly agaric" }) .update(doc! { "$set": { "name": "fly amanita" } }) .upsert(true) .build(), ), WriteModel::UpdateMany( UpdateManyModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "color": "yellow" }) .update(doc! { "$set": { "color": "yellow/orange" } }) .build(), ), ]; let result = client.bulk_write(models).await?; println!("Modified documents: {}", result.modified_count);
Modified documents: 2
删除
要执行批量删除操作,请为每个删除操作创建一个DeleteOneModel或DeleteManyModel实例。 然后,将模型列表传递给bulk_write()方法。 DeleteOneModel仅删除与过滤匹配的一个文档,而DeleteManyModel会删除与过滤匹配的所有文档。
下表描述了您可以通过调用相应的构建器方法来设立的DeleteOneModel和DeleteManyModel字段:
字段 | 说明 |
|---|---|
| 执行操作的命名空间空间。类型: |
| 与要删除的一个或多个文档相匹配的过滤器。在 |
| |
|
例子
此示例将执行以下动作:
在大量中指定一个
DeleteOneModel和一个DeleteManyModel实例。 这些模型包含删除表示db.mushrooms命名空间中的蘑菇的文档的指令。将模型大量传递给
bulk_write()方法。打印已删除文档的数量。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::DeleteOne( DeleteOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "color": "red" }) .build(), ), WriteModel::DeleteMany( DeleteManyModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "edible": true }) .build(), ), ]; let result = client.bulk_write(models).await?; println!("Deleted documents: {}", result.deleted_count);
Deleted documents: 4
返回类型
bulk_write()方法返回一个SummaryBulkWriteResult结构体实例,您可以从中访问权限有关批量操作的信息。
SummaryBulkWriteResult类型具有以下字段:
inserted_count:插入文档的数量matched_count:匹配文档的数量modified_count:更新文档的数量upserted_count:已更新或插入的文档数量deleted_count:已删除文档的数量
您还可以使用verbose_results()方法查看每个操作的详细信息。 verbose_results()方法返回一个VerboseBulkWriteResult结构体实例,其中包含以下字段:
delete_results:每个成功删除操作的结果insert_results:每次成功插入操作的结果update_results:每个成功更新操作的结果summary:每种操作类型的结果摘要
以下示例将verbose_results()方法链接到bulk_write()方法并打印更新和删除操作的结果:
let models = vec![ WriteModel::DeleteOne( DeleteOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "oyster" }) .build(), ), WriteModel::UpdateOne( UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "chanterelle" }) .update(doc! { "$set": { "season": ["July", "August", "September"] } }) .build(), ), ]; let result = client.bulk_write(models).verbose_results().await?; println!( "Update results: {:?}\nDelete results: {:?}\n", result.update_results, result.delete_results );
Update results: {1: UpdateResult { matched_count: 1, modified_count: 1, upserted_id: None }} Delete results: {0: DeleteResult { deleted_count: 1 }}
修改行为
您可以通过设置BulkWriteOptions字段值来修改bulk_write()方法的行为。 要设立这些结构体字段,请将字段的相应方法链接到bulk_write()方法。
BulkWriteOptions结构包含以下字段:
字段 | 说明 | 默认值 |
|---|---|---|
| 操作是否按指定顺序运行。当设立为 |
|
|
|
|
| 任意注释,有助于通过数据库分析器、currentOp 和日志跟踪操作。类型: |
|
| 要应用批量写入中的所有操作的参数名称和值的映射。值必须是常量或不引用文档字段的闭合表达式。类型: |
|
| 用于此批量操作的写关注(write | 继承命名空间的写关注(write concern) |
例子
此示例尝试对mushrooms集合执行更新和插入操作。 以下代码通过将ordered falseordered()方法链接到bulk_write() 方法来将 字段设置为 :
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::UpdateOne(UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "portobello" }) .update(doc! { "$set": { "_id": 123 } }) .upsert(true) .build()), WriteModel::InsertOne(InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "reishi", "color": "red/brown", "edible": true }) .build()), ]; let result = client.bulk_write(models).ordered(false).await?; println!( "Inserted documents: {}\nDeleted documents: {}", result.inserted_count, result.deleted_count );
Error: Error { kind: BulkWrite(BulkWriteError { write_concern_errors: [], write_errors: {0: WriteError { code: 66, code_name: None, message: "Plan executor error during update :: caused by :: Performing an update on the path '_id' would modify the immutable field '_id'", details: None }}, partial_result: Some(Summary(SummaryBulkWriteResult { inserted_count: 1, matched_count: 0, modified_count: 0, upserted_count: 0, deleted_count: 0 })) }), labels: ... }
_id字段不可变,无法在更新操作中更改。由于 UpdateOneModel 包含更新此字段的指令,因此批量操作会返回 BulkWriteError 并仅执行插入操作。如果将 ordered字段设立为 true,则驱动程序在更新操作不成功后不会尝试任何后续操作,驱动程序也不会插入任何文档。
写入混合命名空间
本页前面的示例对db.mushrooms命名空间执行批量操作。 但是,您可以在单个方法调用中对多个命名空间执行批量写入。
以下示例将一个文档插入ingredients.sweet命名空间,并将一个文档插入meals.dessert命名空间:
let sweet: Collection<Document> = client .database("ingredients") .collection("sweet"); let dessert: Collection<Document> = client .database("meals") .collection("dessert"); let models = vec![ InsertOneModel::builder() .namespace(sweet.namespace()) .document(doc! { "name": "brown sugar", "price": 3.99 }) .build(), InsertOneModel::builder() .namespace(dessert.namespace()) .document(doc! { "name": "banana bread", "cook_time": 75 }) .build(), ]; let result = client.bulk_write(models).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
更多信息
要学习;了解有关批量操作的更多信息,请参阅服务器手册中的批量写入操作。
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: