定义
8.0版本新增。
从MongoDB 8.0开始,您可以使用新的 bulkWrite命令在一个请求中对多个集合执行多次插入、更新和删除操作。 现有的 db.collection.bulkWrite()方法仅允许您在一个请求中修改一个集合。
要在bulkWrite命令中指定每个集合,请使用命名空间(数据库和集合名称)。
兼容性
此命令可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
注意
所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
该命令的语法如下:
db.adminCommand( { bulkWrite: 1, // Include the insert, update, and delete operations // in the ops array ops: [ { insert: <integer>, // Namespace ID index for insert operation. // Must match a namespace ID index in // ns specified later in the nsInfo array. document: <document> }, { update: <integer>, // Namespace ID index for update operation filter: <document>, updateMods: <document>, arrayFilters: [ <filterDocument0>, <filterDocument1>, ... ], multi: <bolean>, hint: <document>, constants: <document>, collation: <document> }, { delete: <integer>, // Namespace ID index for delete operation filter: <document>, multi: <boolean>, hint: <document>, collation: <document> }, ... // Additional insert, update, and delete operations in any order ... ], // Include the namespaces with collections to modify // in the nsInfo array. You can add multiple namespaces here. nsInfo: [ { ns: <string>, // Namespace (database and collection name) to modify. // Each operation namespace ID index // specified in the earlier ops array must // match a namespace ID index here. collectionUUID: <string>, encryptionInformation: <document> }, ... // Additional namespaces ... ], // Additional fields ordered: <boolean>, bypassDocumentValidation: <boolean>, comment: <string>, let: <document>, errorsOnly: <boolean>, cursor: { batchSize: <integer> }, writeConcern: <string> } )
在命令语法中,您可以指定多个:
在
ops大量中以任意顺序执行插入、更新和删除操作。nsInfo大量中操作的命名空间。 要将操作与命名空间匹配,请使用相同的命名空间ID索引。 索引从0开始。 您可以使用分片的集合。
命令字段
该命令接受以下字段:
字段 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| 整型 | 必需 | 插入操作的命名空间ID索引,必须与 |
| 文档 | 必需 | 要插入到集合中的文档。 |
| 整型 | 必需 | 更新操作的命名空间ID索引,必须与 |
| 文档 | Optional | 查询选择器,用于限制进行更新或删除操作的文档。 |
| 文档 | Optional | |
| 文档数组 | Optional | 过滤文档数组,指定针对大量字段的更新操作要修改的文档。 有关详细信息,请参阅使用 |
| 布尔 | Optional | 如果 默认值为 |
| 文档 | Optional | 用于文档 |
| 文档 | Optional | 用于聚合管道自定义更新的常量。 |
| 文档 | Optional | 更新或删除操作的排序规则。 |
| 整型 | 必需 | 删除操作的命名空间ID索引,必须与 |
| 字符串 | 必需 | 操作的命名空间(数据库和集合)。 将 |
| 字符串 | Optional | 指定操作集合的UUID十六进制值。 |
| 文档 | Optional | 操作的加密信息模式和令牌。 有关详细信息,请参阅加密模式。 |
| 布尔 | Optional | 如果 有序操作会串行运行。 如果发生错误,将取消所有剩余操作。 无序操作并行运行。 如果发生错误,则运行剩余的所有语句。 服务器可以对这些操作重新排序,以提高性能。 因此,您的应用程序不应依赖于操作的执行顺序。 默认值为 |
| 布尔 | Optional | |
| 字符串 | Optional | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 |
| 文档 | Optional | 包含要在操作中引用的常量列表的文档。 有关 |
| 布尔 | Optional | 如果为 默认值为 |
| 整型 | Optional |
|
| 字符串 | Optional | 写入操作的关注点。 省略使用服务器默认。 |
输出
该命令返回包含以下字段的文档:
字段 | 类型 | 说明 |
|---|---|---|
| 文档 | 游标带有命令结果。 |
| 整型 | 游标标识符。 |
| 文档数组 | 操作结果。 |
| 整型 |
|
| 整型 | 操作索引号,对应于 |
| 整型 | 错误的代码号。 |
| 字符串 | 错误描述。 |
| 文档 | 文档索引键规范是否存在错误。 |
| 文档 | 发生错误的文档索引键值。 |
| 整型 | 受操作影响的文档总数。 |
| 整型 | 更新操作修改的文档数量。 |
| 整型 |
|
| 整型 | 插入的文档数。 |
| 整型 | 匹配的文档数量。 |
| 整型 | 已修改文档的数量。 |
| 整型 | 已更新或插入的文档数量。 |
| 整型 | 已删除文档的数量。 |
| 整型 |
|
注意
输出字段可能会有所不同,具体取决于您在bulkWrite命令中运行的操作。
行为
本部分介绍bulkWrite命令行为。
多文档字段和可重试写入
如果multi字段为true ,则更新或删除操作将更新或删除与文档filter匹配的所有文档。 如果为false ,则操作更新或删除与文档filter匹配的第一个文档。 有关多文档事务的详细信息,请参阅事务。
要启用重试写入,请参阅可重试写入。
您可以使用具有可重试写入功能的bulkWrite插入操作,并将multi字段设立为true 。
您可以使用bulkWrite更新和删除操作,并将multi字段设立为true 。 但是,在将multi设立为true和可重试写入的情况下,您无法使用更新或删除操作。
分片集群中的写关注错误
在版本8.1.2中进行了更改。
当 bulkWrite 在分片集群中的 mongos 上执行时,即使出现一个或多个其他错误,响应中也始终会报告 writeConcernError。在以前的版本中,其他错误有时会导致 bulkWrite 不报告写关注(write concern)错误。
示例,如果文档验证失败,触发 DocumentValidationFailed 错误,并且还发生写关注(write concern)错误,则 DocumentValidationFailed 错误和 writeConcernError 都会在响应的顶级字段中返回。
操作性能
如果将现有的插入、更新和删除命令重写为bulkWrite命令设立errorsOnly设置为true ,则bulkWrite命令具有与现有命令相似的性能。 如果设立errorsOnly设置为false ,性能会变差。
此外,如果您有如下命令序列:
insert update delete
如果将这些命令替换为以下示例片段,则无论其他选项如何,使用以下片段的命令都会更快:
{ bulkWrite: 1, ops: [ insert, update, delete ] }
大部分性能改进是由于网络延迟造成的,网络延迟因实施而异,但示例总是速度更快。
示例
本页上的示例使用 sample_mflix示例数据集中的数据。有关如何将此数据集加载到自管理MongoDB 部署中的详细信息,请参阅加载示例数据集。如果对示例数据库进行了任何修改,则可能需要删除并重新创建数据库才能运行本页上的示例。
单个命名空间批量写入示例
以下bulkWrite示例修改了单个命名空间:
修改users 集合
运行以下bulkWrite命令以对users集合执行插入、更新和删除操作:
db.adminCommand( { bulkWrite: 1, // The ops array contains the insert, update, and delete // operations. ops: [ // Specify the namespace ID index immediately after // the insert, update, and delete text. // For example, "insert: 0" specifies the 0 namespace ID index, // which is the "sample_mflix.users" namespace in nsInfo at the end // of the example. // Insert a user. { insert: 0, document: { _id: ObjectId("67a1b2c3d4e5f6a7b8c9d0e1"), name: "Tyrion Lannister", email: "tyrion.lannister@example.com", password: "$2b$12$UREFwsRUoyF0CRqGNK0LzO0HM/jLhgUCNNIJ9RJAqMUQ74crlJ1Vu" } }, // Update the email for a user named Ned Stark. { update: 0, filter: { name: "Ned Stark" }, updateMods: { $set: { email: "ned.stark.updated@example.com" } } }, // Delete a user with a specific _id. { delete: 0, filter: { _id: ObjectId("67a1b2c3d4e5f6a7b8c9d0e1") } } ], // The nsInfo array contains the namespace to apply the // previous operations to. nsInfo: [ { ns: "sample_mflix.users" } // Namespace ID index is 0. ] } )
users集合位于 sample_mflix数据库中,因此 ns命名空间为 "sample_mflix.users"。命名空间ID索引为 0,它在 ops大量中的插入、更新和删除操作的第一个字段中设立。
检查输出
以下bulkWrite示例输出包含各个ok: 1字段和nErrors: 0 ,表示所有操作均已成功:
{ cursor: { id: Long('0'), firstBatch: [ { ok: 1, idx: 0, n: 1 }, { ok: 1, idx: 1, n: 1, nModified: 1 }, { ok: 1, idx: 2, n: 1 } ], ns: 'admin.$cmd.bulkWrite' }, nErrors: 0, nInserted: 1, nMatched: 1, nModified: 1, nUpserted: 0, nDeleted: 1, ok: 1 }
有关输出字段的详细信息,请参阅前面的输出部分。
多个命名空间批量写入示例
您可以在bulkWrite命令中指定多个命名空间。
以下bulkWrite示例包含针对两个命名空间的插入、更新和删除操作:
修改集合
运行以下 bulkWrite 命令以对 users 和 sample_mflix.theaters 集合执行插入、更新和删除操作:
db.adminCommand( { bulkWrite: 1, // The ops array contains the insert, update, and delete // operations. ops: [ // Specify the namespace ID indexes immediately after // the insert, update, and delete. For example, "insert: 0" // specifies the 0 namespace ID index, which is the "sample_mflix.users" // namespace. And, "insert: 1" specifies "sample_mflix.theaters". // Insert users. // Namespace ID is 0 for "sample_mflix.users", which // is specified as "insert: 0". { insert: 0, document: { _id: ObjectId("67a1b2c3d4e5f6a7b8c9d0e7"), name: "Sansa Stark", email: "sansa.stark@example.com", password: "$2b$12$UREFwsRUoyF0CRqGNK0LzO0HM/jLhgUCNNIJ9RJAqMUQ74crlJ1Vu" } }, { insert: 0, document: { _id: ObjectId("67a1b2c3d4e5f6a7b8c9d0e8"), name: "Bran Stark", email: "bran.stark@example.com", password: "$2b$12$UREFwsRUoyF0CRqGNK0LzO0HM/jLhgUCNNIJ9RJAqMUQ74crlJ1Vu" } }, // Update the email for a user. { update: 0, filter: { name: "Ned Stark" }, updateMods: { $set: { email: "lord.stark@example.com" } } }, // Delete users with a specific email pattern. { delete: 0, filter: { email: { $regex: "bran.stark" } } }, // Update theaters. // Namespace ID is 1 for "sample_mflix.theaters". { update: 1, filter: { theaterId: 1000 }, updateMods: { $set: { "location.address.city": "Minneapolis" } } }, // Delete a theater with a specific _id. { delete: 1, filter: { _id: ObjectId("59a47286cfa9a3a73e51e72c") } }, // Delete theaters in a specific state. { delete: 1, filter: { "location.address.state": "VT" }, multi: true } ], // Namespaces nsInfo: [ { ns: "sample_mflix.users" }, // Namespace ID index is 0. { ns: "sample_mflix.theaters" } // Namespace ID index is 1. ] } )
检查输出
以下bulkWrite示例输出表示操作成功:
{ cursor: { id: Long('0'), firstBatch: [ { ok: 1, idx: 0, n: 1 }, { ok: 1, idx: 1, n: 1 }, { ok: 1, idx: 2, n: 1, nModified: 1 }, { ok: 1, idx: 3, n: 1 }, { ok: 1, idx: 4, n: 1, nModified: 1 }, { ok: 1, idx: 5, n: 1 }, { ok: 1, idx: 6, n: 2 } ], ns: 'admin.$cmd.bulkWrite' }, nErrors: 0, nInserted: 2, nMatched: 2, nModified: 2, nUpserted: 0, nDeleted: 4, ok: 1 }