Database Manual / Reference / Query Language / CRUD Commands

bulkWrite (database command)

Definition定义

bulkWrite

New in version 8.0.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. 从MongoDB 8.0开始,您可以使用新的bulkWrite命令在一个请求中对多个集合执行许多插入、更新和删除操作。The existing db.collection.bulkWrite() method only allows you to modify one collection in one request.现有的db.collection.bulkWrite()方法只允许您在一个请求中修改一个集合。

To specify each collection in the bulkWrite command, use a namespace (database and collection name).要在bulkWrite命令中指定每个集合,请使用命名空间(数据库和集合名称)。

Compatibility兼容性

This command is available in deployments hosted in the following environments:此命令在以下环境中托管的部署中可用:

  • MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud:云中MongoDB部署的完全托管服务

Note

This command is supported in all MongoDB Atlas clusters. 所有MongoDB Atlas集群都支持此命令。For information on Atlas support for all commands, see Unsupported Commands.有关Atlas支持所有命令的信息,请参阅不支持的命令。

  • MongoDB Enterprise: The subscription-based, self-managed version of MongoDB:MongoDB的基于订阅的自我管理版本
  • MongoDB Community: The source-available, free-to-use, and self-managed version of MongoDB:MongoDB的源代码可用、免费使用和自我管理版本

Syntax语法

The command has this syntax:该命令具有以下语法:

db.adminCommand( {
bulkWrite: 1,

// Include the insert, update, and delete operations in the ops array在ops数组中包括插入、更新和删除操作
ops: [
{
insert: <integer>, // Namespace ID index for insert operation.插入操作的命名空间ID索引。
// Must match a namespace ID index in ns specified later in the nsInfo array.必须与nsInfo数组中稍后指定的ns中的命名空间ID索引匹配。
document: <document>
},
{
update: <integer>, // Namespace ID index for update operation更新操作的命名空间ID索引
filter: <document>,
updateMods: <document>,
arrayFilters: [ <filterDocument0>, <filterDocument1>, ... ],
multi: <bolean>,
hint: <document>,
constants: <document>,
collation: <document>
},
{
delete: <integer>, // Namespace ID index for delete operation删除操作的命名空间ID索引
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. 在nsInfo数组中包含要修改集合的命名空间。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.在前面的ops数组中指定的每个操作命名空间ID索引都必须与此处的命名空间ID索引匹配。
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.ops数组中以任何顺序插入、更新和删除操作。

  • Namespaces for the operations in the nsInfo array. nsInfo数组中操作的命名空间。To match the operation to the namespace, use the same namespace ID index. Indexes start at 0. 要将操作与命名空间匹配,请使用相同的命名空间ID索引。索引从0开始。You can use sharded collections.您可以使用分片集合。

Command Fields命令字段

The command takes the following fields:该命令包含以下字段:

Field字段Type类型Necessity必要性Description描述
insertintegerRequired必要的Namespace ID index for an insert operation, which must match a namespace ID index in the ns field in the nsInfo array. Indexes start at 0.插入操作的命名空间ID索引,该索引必须与nsInfo数组中ns字段中的命名空间ID指数匹配。索引从0开始。
documentdocumentRequired必要的Document to insert into the collection.要插入集合的文档。
updateintegerRequired必要的Namespace ID index for an update operation, which must match a namespace ID index in the ns field in the nsInfo array. Indexes start at 0.更新操作的命名空间ID索引,该索引必须与nsInfo数组中ns字段中的命名空间ID指数匹配。索引从0开始。
filterdocumentOptional可选的Query selector to limit the documents for the update or delete operation.
updateModsdocumentOptional可选的Update operation to perform on the collection. You can specify one of these:要对集合执行的更新操作。您可以指定其中之一:
arrayFiltersdocument arrayOptional可选的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 arrayFilters.有关详细信息,请参阅使用arrayFilters的数组更新操作
multibooleanOptional可选的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 Transactions.

Default is false.

hintdocumentOptional可选的Index to use for the document filter. 用于文档筛选器的索引If the index doesn't exist, the update operation returns an error.如果索引不存在,更新操作将返回错误。
constantsdocumentOptional可选的Constants for an aggregation pipeline custom update.
collationdocumentOptional可选的Collation for an update or delete operation.
deleteintegerRequired必要的Namespace ID index for a delete operation, which must match a namespace ID index in the ns field in the nsInfo array. Indexes start at 0.
nsstringRequired必要的Namespace (database and collection) for the operations. Set the namespace ID index for each operation in ops to the matching namespace array index in ns. Indexes start at 0.
collectionUUIDstringOptional可选的UUID hexadecimal value that specifies the collection for the operations.
encryptionInformationdocumentOptional可选的Encryption information schema and tokens for the operation. For details, see Encryption Schemas.
orderedbooleanOptional可选的If true, perform ordered operations. Otherwise, perform unordered operations.

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.因此,您的应用程序不应依赖于操作执行的顺序。

Default is true.

bypassDocumentValidationbooleanOptional可选的If true, the operation bypasses the schema validation rules. If false, the documents must be valid.

Default is false.

commentstringOptional可选的Optional. A user-provided comment to attach to this command. Once set, this comment appears alongside records of this command in the following locations:可选。用户提供了要附加到此命令的注释。设置后,此注释将与此命令的记录一起出现在以下位置:

A comment can be any valid BSON type (string, integer, object, array, etc).

letdocumentOptional可选的Document with a list of constants to reference in the operation. For let examples, see Use Variables in let Option or c Field and Use Variables in let.
errorsOnlybooleanOptional可选的If true, the operation only returns errors and omits other output.

Default is false.

cursor batchSizeintegerOptional可选的Cursor batch size for the bulkWrite command's returned results. For details, see cursor.batchSize().
writeConcernstringOptional可选的Write concern for the operation. Omit to use the server default.操作的写入关注。省略使用服务器默认值。

Output输出

The command returns a document with these fields:该命令返回一个包含以下字段的文档:

Field字段Type类型Description描述
cursordocumentCursor with the command results.带有命令结果的游标。
cursor.idintegerCursor identifier.游标标识符。
cursor.firstBatchdocument arrayResults of the operations.手术结果。
cursor.firstBatch.okinteger1 indicates the operation was successful. Otherwise, 0.1表示操作成功。否则,0
cursor.firstBatch.idxintegerOperation index number, which corresponds to the operation in the ops array. The first operation has an idx value of 0.操作索引号,与ops数组中的操作相对应。第一个操作的idx值为0
cursor.firstBatch.codeintegerCode number for an error.错误代码。
cursor.firstBatch.errmsgstringDescription for an error.错误描述。
cursor.firstBatch.keyPatterndocumentDocument index key specification for an error.文档索引键规范存在错误。
cursor.firstBatch.keyValuedocumentDocument index key value for an error.文档索引键值错误。
cursor.firstBatch.nintegerTotal number of documents affected by an operation.受操作影响的文档总数。
cursor.firstBatch.nModifiedintegerNumber of documents modified by an update operation.更新操作修改的文档数。
nErrorsintegerNumber of errors for the bulkWrite command.bulkWrite命令的错误数。
nInsertedintegerNumber of inserted documents.插入的文档数量。
nMatchedintegerNumber of matched documents.匹配的文档数量。
nModifiedintegerNumber of modified documents.修改的文档数量。
nUpsertedintegerNumber of upserted documents.被打乱的文档数量。
nDeletedintegerNumber of deleted documents.已删除文档的数量。
okinteger1 indicates the bulkWrite command was successful. Otherwise, 0.

Note

The output fields may vary depending on the operations you run in the bulkWrite command.输出字段可能因您在bulkWrite命令中运行的操作而异。

Behavior行为

This section describes the bulkWrite command behavior.本节介绍bulkWrite命令行为。

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 Transactions.

To enable retryable writes, see retryable writes.要启用可重试写入,请参阅可重试写入

You can use bulkWrite insert operations with retryable writes and the multi field set to true.您可以将bulkWrite插入操作与可重试的写入操作一起使用,并将multi字段设置为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.

Write Concern Errors in Sharded Clusters分片集群中的写入关注错误

Changed in version 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.

For example, if a document fails validation, triggering a DocumentValidationFailed error, and a write concern error also occurs, both the DocumentValidationFailed error and the writeConcernError are returned in the top-level field of the response.

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.大多数性能改进是由于网络延迟,网络延迟因您的实现而异,但示例总是更快。

Examples例子

This section contains bulkWrite command examples.本节包含bulkWrite命令示例。

Single Namespace Bulk Write Example

The following bulkWrite example modifies a single namespace:

1

Create the pizzas example collection创建披萨示例集合

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 }
] )
2

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.

3

Examine the output检查输出

The following bulkWrite example output, with various ok: 1 fields and nErrors: 0, indicates all operations were successful:以下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 earlier Output section.

Multiple Namespaces Bulk Write Example多命名空间批量写入示例

You can specify multiple namespaces in a bulkWrite command.您可以在bulkWrite命令中指定多个命名空间。

The following bulkWrite example contains insert, update, and delete operations for two namespaces:以下bulkWrite示例包含两个命名空间的插入、更新和删除操作:

1

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 }
] )
2

Create the pizza orders example collection

Run:

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" ) }
] )
3

Modify the example collections修改示例集合

Run the following bulkWrite command to perform insert, update, and delete operations on the example collections:运行以下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.
]
} )
4

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:

1

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 }
] )
2

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
} )
3

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 Output section.有关输出字段的详细信息,包括错误代码和消息,请参阅前面的输出部分。

Bulk Write Example with errorsOnly Enabled带错误的批量写入示例仅启用

The following bulkWrite example sets errorsOnly to true to only show the error output:以下bulkWrite示例将errorsOnly设置为true,仅显示错误输出:

1

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 }
] )
2

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
} )
3

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
}

Learn More