Docs 菜单
Docs 主页
/ / /
Rust 驱动程序
/ / /

批量操作

在此页面上

  • Overview
  • 样本数据
  • 批量操作类型
  • Insert
  • 替换
  • Update
  • 删除
  • 返回类型
  • 修改行为
  • 例子
  • 写入混合命名空间
  • 更多信息

在本指南中,您可以学习;了解如何使用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()方法调用中执行多种类型的写入操作。 要查看将UpdateOneModelInsertOneModel传递给同一bulk_write()调用的示例,请参阅本指南中的修改行为示例

要执行批量插入操作,请为要插入的每个文档创建一个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结构类型的实例:

#[derive(Serialize)]
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

要执行批量更新操作,请为要进行的每次更新创建一个UpdateOneModelUpdateManyModel实例。 然后,将模型列表传递给bulk_write()方法。 UpdateOneModel仅更新与过滤匹配的一个文档,而UpdateManyModel会更新与过滤匹配的所有文档。

下表描述了您可以通过调用相应的构建器方法来设立的UpdateOneModelUpdateManyModel字段:

字段
说明
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

要执行批量删除操作,请为每个删除操作创建一个DeleteOneModelDeleteManyModel实例。 然后,将模型列表传递给bulk_write()方法。 DeleteOneModel仅删除与过滤匹配的一个文档,而DeleteManyModel会删除与过滤匹配的所有文档。

下表描述了您可以通过调用相应的构建器方法来设立的DeleteOneModelDeleteManyModel字段:

字段
说明
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 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

要学习;了解有关批量操作的更多信息,请参阅服务器手册中的批量写入操作

后退

删除