bulkWrite
定义
8.0版本新增。
Starting in MongoDB 8.0, you can use the new bulkWrite
command to perform many insert, update, and delete operations on
multiple collections in one request. The existing
db.collection.bulkWrite()
method only allows you to modify one
collection in one request.
To specify each collection in the bulkWrite
command, use a
namespace (database and collection name).
语法
该命令的语法如下:
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> } )
In the command syntax, you can specify multiple:
Insert, update, and delete operations in any order in the
ops
array.Namespaces for the operations in the
nsInfo
array. To match the operation to the namespace, use the same namespace ID index. Indexes start at0
. You can use sharded collections.
命令字段
该命令接受以下字段:
字段 | 类型 | 必要性 | 说明 |
---|---|---|---|
| 整型 | 必需 | Namespace ID index for an insert operation, which must match a
namespace ID index in the |
| 文档 | 必需 | Document to insert into the collection. |
| 整型 | 必需 | Namespace ID index for an update operation, which must match a
namespace ID index in the |
| 文档 | Optional | Query selector to limit the documents for the update or delete operation. |
| 文档 | Optional | Update operation to perform on the collection. You can specify one of these:
|
| document array | Optional | Array of filter documents that specify the documents to modify for an update operation on an array field. For details, see Array Update Operations with |
| 布尔 | Optional | If the 默认值为 |
| 文档 | Optional | Index to use for the document |
| 文档 | Optional | Constants for an 聚合管道 custom update. |
| 文档 | Optional | 排序规则 for an update or delete operation. |
| 整型 | 必需 | Namespace ID index for a delete operation, which must match a
namespace ID index in the |
| 字符串 | 必需 | Namespace (database and collection) for the operations. Set the
namespace ID index for each operation in |
| 字符串 | Optional | UUID hexadecimal value that specifies the collection for the operations. |
| 文档 | Optional | Encryption information schema and tokens for the operation. For details, see 加密模式. |
| 布尔 | Optional | If Ordered operations run in series. If an error occurs, any remaining operations are cancelled. Unordered operations run in parallel. If an error occurs, any remaining statements are run. The operations may be reordered by the server to increase performance. Therefore, your applications should not depend on the order of operation execution. 默认值为 |
| 布尔 | Optional | If 默认值为 |
| 字符串 | Optional | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 |
| 文档 | Optional | Document with a list of constants to reference in the operation.
For |
| 布尔 | Optional | If 默认值为 |
| 整型 | Optional | Cursor batch size for the |
| 字符串 | Optional | Write concern for the operation. Omit to use the server default. |
输出
The command returns a document with these fields:
字段 | 类型 | 说明 |
---|---|---|
| 文档 | Cursor with the command results. |
| 整型 | Cursor identifier. |
| document array | Results of the operations. |
| 整型 |
|
| 整型 | Operation index number, which corresponds to the operation in the
|
| 整型 | Code number for an error. |
| 字符串 | Description for an error. |
| 字符串 | Document index key specification for an error. |
| 字符串 | Document index key value for an error. |
| 整型 | Total number of documents affected by an operation. |
| 整型 | Number of documents modified by an update operation. |
| 整型 | Number of errors for the |
| 整型 | Number of inserted documents. |
| 整型 | Number of matched documents. |
| 整型 | Number of modified documents. |
| 整型 | Number of upserted documents. |
| 整型 | Number of deleted documents. |
| 整型 |
|
注意
The output fields may vary depending on the operations you run in the
bulkWrite
command.
行为
This section describes the bulkWrite
command behavior.
Multiple Document Field and Retryable Writes
If the multi
field is true
, the update or delete operation
updates or deletes all documents that match the document filter
. If
false
, the operation updates or deletes the first document that
matches the document filter
. For details on multi-document
transactions, see 事务.
To enable retryable writes, see retryable writes.
You can use bulkWrite
insert operations with retryable writes and
the multi
field set to true
.
You can use bulkWrite
update and delete operations with the
multi
field set to true
. But, you cannot use update or delete
operations with both multi
set to true
and retryable writes.
Operation Performance
If you rewrite existing insert, update, and delete commands as a
bulkWrite
command and set errorsOnly
to true
, the
bulkWrite
command has similar performance as the existing commands.
If you set errorsOnly
to false
, performance is worse.
In addition, if you have a sequence of commands like this:
insert update delete
If you replace those commands with the following example fragment, then the command with the following fragment is faster regardless of other options:
{ bulkWrite: 1, ops: [ insert, update, delete ] }
Most of the performance improvement is because of network latency, which is variable depending on your implementation, but the example is always faster.
示例
This section contains bulkWrite
command examples.
Single Namespace Bulk Write Example
The following bulkWrite
example modifies a single namespace:
Modify the pizzas example collection
Run the following bulkWrite
command to perform insert, update,
and delete operations on the pizzas
collection:
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. ] } )
The pizzas
collection is in the default test
database, so
the ns
namespace is "test.pizzas"
. The namespace ID index
is 0
, which is set in the first field of the insert, update,
and delete operations in the ops
array.
Examine the output
The following bulkWrite
example output, with various ok: 1
fields and nErrors: 0
, indicates all operations were
successful:
{ 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 earlier 输出 section.
Multiple Namespaces Bulk Write Example
You can specify multiple namespaces in a bulkWrite
command.
The following bulkWrite
example contains insert, update, and delete
operations for two namespaces:
Create the pizzas example collection
If you already have the pizzas
collection in your test
database, use the db.collection.drop()
method to drop it
first and then run:
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 } ] )
Create the pizza orders example collection
运行:
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" ) } ] )
Modify the example collections
Run the following bulkWrite
command to perform insert, update,
and delete operations on the example collections:
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. ] } )
Examine the output
The following bulkWrite
example output indicates the
operations were successful:
{ 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 }
Operations with Errors Bulk Write Example
The following bulkWrite
example contains operations with errors and
operations that don't change any documents:
Create the pizzas example collection
If you already have the pizzas
collection in your test
database, use the db.collection.drop()
method to drop it
first and then run:
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 } ] )
Attempt to modify the pizzas example collection
Run the following bulkWrite
command to perform insert, update,
and delete operations on the pizzas
collection:
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 } )
Examine the output
The following bulkWrite
example output shows the errors:
{ 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 }
For details about the output fields, including the error codes and messages, see the earlier 输出 section.
Bulk Write Example with errorsOnly Enabled
The following bulkWrite
example sets errorsOnly
to true
to
only show the error output:
Create the pizzas example collection
If you already have the pizzas
collection in your test
database, use the db.collection.drop()
method to drop it
first and then run:
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 } ] )
Attempt to modify the pizzas example collection
Run the following bulkWrite
command to perform insert, update,
and delete operations on the pizzas
collection with
errorsOnly
set to 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 } )
Examine the output
The following bulkWrite
example output shows the errors:
{ 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 }