定义
8.0版本新增。
从MongoDB8.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> }, maxTimeMS: <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 |
|
| non-negative integer | Optional | 指定时间限制(以毫秒为单位)。如果您未指定 MongoDB 使用与 |
| 字符串 | Optional | 写入操作的关注点。 省略使用服务器默认。 |
输出
该命令返回包含以下字段的文档:
字段 | 类型 | 说明 |
|---|---|---|
| 文档 | 游标带有命令结果。 |
| 整型 | 游标标识符。 |
| 文档数组 | 操作结果。 |
| 整型 |
|
| 整型 | 操作索引号,对应于 |
| 整型 | 错误的代码号。 |
| 字符串 | 错误描述。 |
| 文档 | 文档索引键规范是否存在错误。 |
| 文档 | 发生错误的文档索引键值。 |
| 整型 | 受操作影响的文档总数。 |
| 整型 | 更新操作修改的文档数量。 |
| 整型 |
|
| 整型 | 插入的文档数。 |
| 整型 | 匹配的文档数量。 |
| 整型 | 已修改文档的数量。 |
| 整型 | 已更新或插入的文档数量。 |
| 整型 | 已删除文档的数量。 |
| 整型 |
|
注意
输出字段可能会有所不同,具体取决于您在bulkWrite命令中运行的操作。
行为
多文档字段和可重试写入
如果multi字段为true ,则更新或删除操作将更新或删除与文档filter匹配的所有文档。 如果为false ,则操作更新或删除与文档filter匹配的第一个文档。 有关多文档事务的详细信息,请参阅事务。
要启用重试写入,请参阅可重试写入。
您可以使用具有可重试写入功能的bulkWrite插入操作,并将multi字段设立为true 。
您可以使用bulkWrite更新和删除操作,并将multi字段设立为true 。 但是,在将multi设立为true和可重试写入的情况下,您无法使用更新或删除操作。
分片集群中的写关注错误
在版本8.1.2中进行了更改。
When bulkWrite executes on mongos in a sharded cluster, a writeConcernError is always reported in the response, even when one or more other errors occur. In previous releases, other errors sometimes caused bulkWrite to not report write concern errors.
示例,如果文档验证失败,触发 DocumentValidationFailed 错误,并且还发生写关注(write concern)错误,则 DocumentValidationFailed 错误和 writeConcernError 都会在响应的顶级字段中返回。
操作性能
如果将现有的插入、更新和删除命令重写为bulkWrite命令设立errorsOnly设置为true ,则bulkWrite命令具有与现有命令相似的性能。 如果设立errorsOnly设置为false ,性能会变差。
用单个 bulkWrite 命令替换多个独立的写入命令可以减少网络延迟,从而提高性能。例如,示例,考虑以下序列:
insert update delete
将此序列替换为单个 bulkWrite 命令:
{ bulkWrite: 1, ops: [ insert, update, delete ] }
示例
单个命名空间批量写入示例
以下bulkWrite示例修改了单个命名空间:
修改披萨示例集合
运行以下bulkWrite命令以对pizzas集合执行插入、更新和删除操作:
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 "test.pizzas" namespace in nsInfo at the end // of the example. // Insert a pizza. { insert: 0, document: { _id: 4, type: "sausage", size: "small", price: 12 } }, // Update the price for medium pizzas. { update: 0, filter: { size: "medium" }, updateMods: { $set: { price: 15 } } }, // Delete the pizza with an _id of 2. { delete: 0, filter: { _id: 2 } } ], // The nsInfo array contains the namespace to apply the // previous operations to. nsInfo: [ { ns: "test.pizzas" } // Namespace ID index is 0. ] } )
pizzas集合位于默认的test数据库中,因此ns命名空间为"test.pizzas" 。 命名空间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 }
For details about the output fields, see the Output section.
多个命名空间批量写入示例
您可以在bulkWrite命令中指定多个命名空间。
以下bulkWrite示例包含针对两个命名空间的插入、更新和删除操作:
创建披萨示例集合
如果test数据库中已有pizzas集合,请先使用db.collection.drop()方法将其删除,然后运行:
db.pizzas.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 4 }, { _id: 1, type: "cheese", size: "medium", price: 7 }, { _id: 2, type: "vegan", size: "large", price: 8 } ] )
创建披萨订单示示例集合
运行:
db.pizzaOrders.insertMany( [ { _id: 0, type: "pepperoni", number: 5, orderDate: new Date( "2023-01-15T12:00:00Z" ) }, { _id: 1, type: "cheese", number: 15, orderDate: new Date( "2023-01-23T11:12:32Z" ) }, { _id: 2, type: "vegan", number: 20, orderDate: new Date( "2023-03-20T10:01:12Z" ) } ] )
修改示例集合
运行以下bulkWrite命令,对示例集合执行插入、更新和删除操作:
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 "test.pizzas" // namespace. And, "insert: 1" specifies "test.pizzaOrders". // Insert pizzas. // Namespace ID is 0 for "test.pizzas", which // is specified as "insert: 0". { insert: 0, document: { _id: 5, type: "sausage", size: "small", price: 12 } }, { insert: 0, document: { _id: 6, type: "vegan cheese", size: "large", price: 25 } }, // Update the price for cheese pizzas. { update: 0, filter: { type: "cheese" }, updateMods: { $set: { price: 15 } } }, // Delete pizzas with a price less than 7. { delete: 0, filter: { price: { $lt: 7 } } }, // Insert pizza orders. // Namespace ID is 1 for "test.pizzaOrders". { insert: 1, document: { _id: 3, type: "sausage", number: 7, orderDate: new Date( "2023-04-15T12:02:15Z" ) } }, { insert: 1, document: { _id: 4, type: "vegan", number: 16, orderDate: new Date( "2023-05-12T11:03:11Z" ) } }, // Update the number of pizza orders for cheese pizzas. { update: 1, filter: { type: "cheese" }, updateMods: { $set: { number: 50 } } }, // Delete the pizza order with an _id of 2. { delete: 1, filter: { _id: 2 } }, // Delete pizza orders placed before March 15, 2023. { delete: 1, filter: { orderDate: { $lte: ISODate( "2023-03-15T00:00:00Z" ) } } } ], // Namespaces nsInfo: [ { ns: "test.pizzas" }, // Namespace ID index is 0. { ns: "test.pizzaOrders" } // 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 }, { ok: 1, idx: 5, n: 1 }, { ok: 1, idx: 6, n: 1, nModified: 1 }, { ok: 1, idx: 7, n: 1 }, { ok: 1, idx: 8, n: 1 } ], ns: 'admin.$cmd.bulkWrite' }, nErrors: 0, nInserted: 4, nMatched: 2, nModified: 2, nUpserted: 0, nDeleted: 3, ok: 1 }
出现错误的操作批量写入示例
以下bulkWrite示例包含出现错误的操作和不更改任何文档的操作:
创建披萨示例集合
如果test数据库中已有pizzas集合,请先使用db.collection.drop()方法将其删除,然后运行:
db.pizzas.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 4 }, { _id: 1, type: "cheese", size: "medium", price: 7 }, { _id: 2, type: "vegan", size: "large", price: 8 } ] )
尝试修改披萨示例集合
运行以下bulkWrite命令以对pizzas集合执行插入、更新和删除操作:
db.adminCommand( { bulkWrite: 1, // The ops array contains the insert, update, and delete // operations. ops: [ // The namespace ID indexes are specified immediately after // the insert, update, and delete text. // For example, "insert: 0" specifies the 0 namespace ID index, // which is the "test.pizzas" namespace in nsInfo. // Attempt to add a duplicate document with an // _id of 1, which already exists and causes an error. { insert: 0, document: { _id: 1, type: "tomato", size: "small", price: 12 } }, // Attempt to add another duplicate document. { insert: 0, document: { _id: 2, type: "pepper", size: "small", price: 12 } }, // Attempt to change the price for extra large pizzas, // which don't exist. This doesn't cause an error but // doesn't update any documents. { update: 0, filter: { size: "extra large" }, updateMods: { $set: { price: 15 } } }, // Attempt to remove a document that doesn't exist. // This doesn't cause an error but doesn't delete any documents. { delete: 0, filter: { _id: 8 } } ], // The nsInfo array contains the namespace to apply the // previous operations to. nsInfo: [ { ns: "test.pizzas" } // Namespace ID index is 0. ], // Set the ordered field to false to run the remaining operations // after an operation returns an error. ordered: false } )
检查输出
以下bulkWrite示例输出显示了这些错误:
{ cursor: { id: Long("0"), firstBatch: [ { ok: 0, idx: 0, code: 11000, errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 1 }', keyPattern: { _id: 1 }, keyValue: { _id: 1 }, n: 0 }, { ok: 0, idx: 1, code: 11000, errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 2 }', keyPattern: { _id: 1 }, keyValue: { _id: 2 }, n: 0 }, { ok: 1, idx: 2, n: 0, nModified: 0 }, { ok: 1, idx: 3, n: 0 } ], ns: 'admin.$cmd.bulkWrite' }, nErrors: 2, nInserted: 0, nMatched: 0, nModified: 0, nUpserted: 0, nDeleted: 0, ok: 1 }
有关输出字段的详细信息,包括错误代码和消息,请参阅前面的输出部分。
启用errorsOnly 的批量写入示例
以下bulkWrite示例将errorsOnly设置为true以仅显示错误输出:
创建披萨示例集合
如果test数据库中已有pizzas集合,请先使用db.collection.drop()方法将其删除,然后运行:
db.pizzas.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 4 }, { _id: 1, type: "cheese", size: "medium", price: 7 }, { _id: 2, type: "vegan", size: "large", price: 8 } ] )
尝试修改披萨示例集合
运行以下bulkWrite命令,对pizzas集合执行插入、更新和删除操作,其中errorsOnly设立为true :
db.adminCommand( { bulkWrite: 1, // The ops array contains the insert, update, and delete // operations. ops: [ // The namespace ID indexes are specified immediately after // the insert, update, and delete text. // For example, "insert: 0" specifies the 0 namespace ID index, // which is the "test.pizzas" namespace in nsInfo. // Attempt to add a duplicate document with an // _id of 1, which already exists and causes an error. { insert: 0, document: { _id: 1, type: "tomato", size: "small", price: 12 } }, // Attempt to add another duplicate document. { insert: 0, document: { _id: 2, type: "pepper", size: "small", price: 12 } }, // Attempt to change the price for extra large pizzas, // which don't exist. This doesn't cause an error but // doesn't update any documents. { update: 0, filter: { size: "extra large" }, updateMods: { $set: { price: 15 } } }, // Attempt to remove a document that doesn't exist. // This doesn't cause an error but doesn't delete any documents. { delete: 0, filter: { _id: 8 } } ], // The nsInfo array contains the namespace to apply the // previous operations to. nsInfo: [ { ns: "test.pizzas" } // Namespace ID index is 0. ], // Set the ordered field to false to run the remaining operations // after an operation returns an error. ordered: false, // Set the errorsOnly field to true to only output the errors. errorsOnly: true } )
检查输出
以下bulkWrite示例输出显示了这些错误:
{ cursor: { id: Long("0"), firstBatch: [ { ok: 0, idx: 0, code: 11000, errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 1 }', keyPattern: { _id: 1 }, keyValue: { _id: 1 }, n: 0 }, { ok: 0, idx: 1, code: 11000, errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 2 }', keyPattern: { _id: 1 }, keyValue: { _id: 2 }, n: 0 }, ], ns: 'admin.$cmd.bulkWrite' }, nErrors: 2, nInserted: 0, nMatched: 0, nModified: 0, nUpserted: 0, nDeleted: 0, ok: 1 }