对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

批量操作

在本指南中,您可以学习如何使用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

执行插入操作的命名空间空间。类型:
Namespace

document

要插入的文档。
类型: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

执行操作的命名空间空间。类型:
Namespace

filter

与要替换的文档匹配的过滤器。
类型:Document

replacement

替换文档。
类型:Document

collation

(可选)对结果进行排序时使用的排序规则。要学习;了解有关排序规则的更多信息,请参阅排序规则指南。类型:
Document

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 索引指南。类型:
Bson

upsert

(可选)如果没有文档与过滤器匹配,是否创建新文档。
默认下,此字段设立为 false
类型: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

执行操作的命名空间空间。类型:
Namespace

filter

与要更新的一个或多个文档相匹配的过滤器。在 UpdateOneModel 中指定时,只更新第一个匹配的文档。在 UpdateManyModel 中指定时,所有匹配的文档都将更新。
类型:Document

update

要执行的更新。
类型:UpdateModifications

array_filters

(可选)一设立过滤器,用于指定在更新数组值字段时要对哪些数组元素进行更新。
类型:Array

collation

(可选)对结果进行排序时使用的排序规则。要学习;了解有关排序规则的更多信息,请参阅排序规则指南。类型:
Document

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 索引指南。类型:
Bson

upsert

(可选)如果没有文档与过滤器匹配,是否创建新文档。默认下,此字段设立为 false
类型: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

执行操作的命名空间空间。类型:
Namespace

filter

与要删除的一个或多个文档相匹配的过滤器。在 DeleteOneModel 中指定时,仅删除第一个匹配的文档。在 DeleteManyModel 中指定时,将删除所有匹配的文档。
类型:Document

collation

(可选)对结果进行排序时使用的排序规则。要学习;了解有关排序规则的更多信息,请参阅排序规则指南。类型:
Document

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 索引指南。类型:
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

操作是否按指定顺序运行。当设立为
true时,一个失败的操作会阻止后续操作运行。设立为
false时,如果写入操作失败,服务器将继续尝试写入操作。类型:
bool

true

bypass_document_validation


是否绕过文档级验证。类型:bool

false

comment

任意注释,有助于通过数据库分析器、currentOp 和日志跟踪操作。类型:
Bson

None

let_vars

要应用批量写入中的所有操作的参数名称和值的映射。值必须是常量或不引用文档字段的闭合表达式。类型:
Document

None

write_concern

用于此批量操作的写关注(write
concern)。类型: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

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

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: