批量操作
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
字段:
字段 | 说明 |
---|---|
namespace | The namespace on which the insert is performed. Type: Namespace |
document | The document to insert. Type: Document |
插入文档示例
此示例将执行以下动作:
在大量中指定两个
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
字段:
字段 | 说明 |
---|---|
namespace | The namespace on which the operation is performed. Type: Namespace |
filter | The filter that matches the document you want to replace. Type: Document |
replacement | The replacement document. Type: Document |
collation | (Optional) The collation to use when sorting results. To learn more about collations,
see the Collations guide. Type: Document |
hint | (Optional) The index to use for the operation. To learn more about
indexes, see the Indexes guide. Type: Bson |
upsert | (Optional) Whether a new document is created if no document matches the filter. By default, this field is set to false .Type: bool |
例子
此示例将执行以下动作:
在大量中指定两个
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
字段:
字段 | 说明 |
---|---|
namespace | The namespace on which the operation is performed. Type: Namespace |
filter | The filter that matches one or more documents you want to update. When specified in an UpdateOneModel ,
only the first matching document will be updated. When specified in an UpdateManyModel , all
matching documents will be updated.Type: Document |
update | The update to perform. Type: UpdateModifications |
array_filters | (Optional) A set of filters specifying which array elements an update applies to if you are updating an
array-valued field. Type: Array |
collation | (Optional) The collation to use when sorting results. To learn more about collations,
see the Collations guide. Type: Document |
hint | (Optional) The index to use for the operation. To learn more about
indexes, see the Indexes guide. Type: Bson |
upsert | (Optional) Whether a new document is created if no document matches the filter.
By default, this field is set to false .Type: bool |
例子
此示例将执行以下动作:
在大量中指定一个
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
字段:
字段 | 说明 |
---|---|
namespace | The namespace on which the operation is performed. Type: Namespace |
filter | The filter that matches one or more documents you want to delete. When specified in a DeleteOneModel ,
only the first matching document will be deleted. When specified in a DeleteManyModel , all
matching documents will be deleted.Type: Document |
collation | (Optional) The collation to use when sorting results. To learn more about collations,
see the Collations guide. Type: Document |
hint | (Optional) The index to use for the operation. To learn more about
indexes, see the Indexes guide. Type: Bson |
例子
此示例将执行以下动作:
在大量中指定一个
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
结构包含以下字段:
字段 | 说明 | 默认值 |
---|---|---|
ordered | Whether the operations run in the order in which they were specified. When set to true , one failed operation prevents subsequent operations from running.When set to false , the server continues to attempt write operations if one fails.Type: bool | true |
bypass_document_validation | Whether document-level validation is bypassed. Type: bool | false |
comment | An arbitrary comment to help trace the operation through the database profiler, currentOp,
and logs. Type: Bson | None |
let_vars | A map of parameter names and values to apply to all operations within the bulk write.
Values must be constant or closed expressions that do not reference document fields. Type: Document | None |
write_concern | The write concern to use for this bulk operation. Type: WriteConcern | 继承命名空间的写关注(write concern) |
例子
此示例尝试对mushrooms
集合执行更新和插入操作。 以下代码通过将ordered
false
ordered()
方法链接到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
更多信息
要学习;了解有关批量操作的更多信息,请参阅服务器手册中的批量写入操作。