db.collection.bulkWrite()

On this page本页内容

Definition定义

db.collection.bulkWrite()

mongo Shell Method

This page documents the mongo shell method, and does not refer to the MongoDB Node.js driver (or any other driver) method. 本页记录了mongo shell方法,未提及MongoDB Node.js驱动程序(或任何其他驱动程序)方法。For corresponding MongoDB driver API, refer to your specific MongoDB driver documentation instead.有关相应的MongoDB驱动程序API,请参阅特定的MongoDB驱动程序文档。

New in version 3.2.版本3.2中的新功能。

Performs multiple write operations with controls for order of execution.使用执行顺序控件执行多个写操作。

db.collection.bulkWrite() has the following syntax:语法如下所示:

db.collection.bulkWrite(
   [ <operation 1>, <operation 2>, ... ],
   {
      writeConcern : <document>,
      ordered : <boolean>
   }
)
Parameter参数Type类型Description描述
operations array

An array of bulkWrite() write operations.bulkWrite()写入操作的数组。

Valid operations are:有效操作包括:

See Write Operations for usage of each operation.有关每个操作的用法,请参阅写入操作

writeConcern document

Optional.可选。A document expressing the write concern. 表达写关注点的文档。Omit to use the default write concern.忽略使用默认的写关注点。

Do not explicitly set the write concern for the operation if run in a transaction. 如果在事务中运行,请不要显式设置操作的写入关注点。To use write concern with transactions, see Transactions and Write Concern.要将写关注点用于事务,请参阅事务和写关注点

ordered boolean

Optional.可选。A boolean specifying whether the mongod instance should perform an ordered or unordered operation execution. 一个布尔值,指定mongod实例应该执行有序还是无序的操作执行。Defaults to true.默认为true

See Execution of Operations请参阅操作的执行

Returns:
  • A boolean acknowledged as true if the operation ran with write concern or false if write concern was disabled.如果操作运行时存在写问题,则布尔值acknowledgedtrue;如果写问题被禁用,则布尔值acknowledgedfalse
  • A count for each write operation.每次写入操作的计数。
  • An array containing an _id for each successfully inserted or upserted documents.包含每个成功插入或升级文档的_id的数组。

Behavior行为

bulkWrite() takes an array of write operations and executes each of them. 取用一个写操作数组并执行每个操作。By default operations are executed in order. 默认情况下,操作是按顺序执行的。See Execution of Operations for controlling the order of write operation execution.有关控制写入操作执行顺序的信息,请参阅操作执行

Write Operations写操作

insertOne

Inserts a single document into the collection.将单个文档插入到集合中。

db.collection.bulkWrite( [
   { insertOne : { "document" : <document> } }
] )

See db.collection.insertOne().请参阅db.collection.insertOne()

updateOne and updateMany

updateOne updates a single document in the collection that matches the filter. 更新集合中与筛选器匹配的单个文档。If multiple documents match, updateOne will update the first matching document only.如果多个文档匹配,updateOne将只更新第一个匹配的文档。

db.collection.bulkWrite( [
   { updateOne :
      {
         "filter": <document>,
         "update": <document or pipeline>,            // Changed in 4.2
         "upsert": <boolean>,
         "collation": <document>,                     // Available starting in 3.4
         "arrayFilters": [ <filterdocument1>, ... ],  // Available starting in 3.6
         "hint": <document|string>                    // Available starting in 4.2.1
      }
   }
] )

updateMany updates all documents in the collection that match the filter.更新集合中与筛选器匹配的所有文档。

db.collection.bulkWrite( [
   { updateMany :
      {
         "filter" : <document>,
         "update" : <document or pipeline>,          // Changed in MongoDB 4.2
         "upsert" : <boolean>,
         "collation": <document>,                    // Available starting in 3.4
         "arrayFilters": [ <filterdocument1>, ... ], // Available starting in 3.6
         "hint": <document|string>                   // Available starting in 4.2.1
      }
   }
] )
Field字段Notes备注
filter The selection criteria for the update. 更新的选择标准。The same query selectors as in the db.collection.find() method are available.db.collection.find()方法中相同的查询选择器可用。
update

The update operation to perform. 要执行的更新操作。Can specify either:可以指定:

upsert

Optional.可选。A boolean to indicate whether to perform an upsert.指示是否执行向上插入的布尔值。

By default, upsert is false.默认情况下,upsertfalse

arrayFilters Optional.可选。An array of filter documents that determine which array elements to modify for an update operation on an array field.筛选文档的数组,用于确定要为数组字段上的更新操作修改哪些数组元素。
collation Optional.可选。Specifies the collation to use for the operation.指定要用于该操作的排序规则
hint

Optional.可选。The index to use to support the update filter. 用于支持更新筛选器的索引If you specify an index that does not exist, the operation errors.如果指定的索引不存在,则操作将出错。

New in version 4.2.1.

For details, see db.collection.updateOne() and db.collection.updateMany().有关详细信息,请参阅db.collection.updateOne()db.collection.updateMany()

replaceOne

replaceOne replaces a single document in the collection that matches the filter. replaceOne替换集合中与筛选器匹配的单个文档。If multiple documents match, replaceOne will replace the first matching document only.如果多个文档匹配,replaceOne将仅替换第一个匹配的文档。

db.collection.bulkWrite([
   { replaceOne :
      {
         "filter" : <document>,
         "replacement" : <document>,
         "upsert" : <boolean>,
         "collation": <document>,                    // Available starting in 3.4
         "hint": <document|string>                   // Available starting in 4.2.1
      }
   }
] )
Field字段Notes备注
filter The selection criteria for the replacement operation. 更换操作的选择标准。The same query selectors as in the db.collection.find() method are available.db.collection.find()方法中相同的查询选择器可用。
replacement The replacement document. 替换文件。The document cannot contain update operators.文档不能包含更新运算符
upsert Optional.可选。A boolean to indicate whether to perform an upsert. 指示是否执行向上插入的布尔值。By default, upsert is false.默认情况下,upsertfalse
collation Optional.可选。Specifies the collation to use for the operation.指定要用于该操作的排序规则
hint

Optional.可选。The index to use to support the update filter. 用于支持更新filter索引If you specify an index that does not exist, the operation errors.如果指定的索引不存在,则操作将出错。

New in version 4.2.1.

For details, see to db.collection.replaceOne().有关详细信息,请参阅

deleteOne and deleteMany

deleteOne deletes a single document in the collection that match the filter. 删除集合中与筛选器匹配的单个文档。If multiple documents match, deleteOne will delete the first matching document only.如果多个文档匹配,deleteOne将仅删除第一个匹配的文档。

db.collection.bulkWrite([
   { deleteOne : {
      "filter" : <document>,
      "collation" : <document>                   // Available starting in 3.4
   } }
] )

deleteMany deletes all documents in the collection that match the filter.删除集合中与筛选器匹配的所有文档。

db.collection.bulkWrite([
   { deleteMany: {
      "filter" : <document>,
      "collation" : <document>                    // Available starting in 3.4
   } }
] )
Field字段Notes备注
filter The selection criteria for the delete operation. 删除操作的选择标准。The same query selectors as in the db.collection.find() method are available.db.collection.find()方法中相同的查询选择器可用。
collation Optional.可选。Specifies the collation to use for the operation.指定要用于该操作的排序规则

For details, see db.collection.deleteOne() and db.collection.deleteMany().有关详细信息,请参阅db.collection.deleteOne()db.collection.deleteMany()

_id Field字段

If the document does not specify an _id field, then mongod adds the _id field and assign a unique ObjectId for the document before inserting or upserting it. 如果文档未指定_id字段,则mongod会添加_id字段,并在插入或更新文档之前为其指定唯一的ObjectIdMost drivers create an ObjectId and insert the _id field, but the mongod will create and populate the _id if the driver or application does not.大多数驱动程序创建ObjectId并插入_id字段,但如果驱动程序或应用程序不创建并填充_idmongod将创建并填充。

If the document contains an _id field, the _id value must be unique within the collection to avoid duplicate key error.如果文档包含_id字段,则_id值在集合中必须是唯一的,以避免重复键错误。

Update or replace operations cannot specify an _id value that differs from the original document.更新或替换操作无法指定与原始文档不同的_id值。

Execution of Operations执行行动

The ordered parameter specifies whether bulkWrite() will execute operations in order or not. ordered参数指定bulkWrite()是否按顺序执行操作。By default, operations are executed in order.默认情况下,操作按顺序执行。

The following code represents a bulkWrite() with five operations.下面的代码表示包含五个操作的bulkWrite()

db.collection.bulkWrite(
   [
      { insertOne : <document> },
      { updateOne : <document> },
      { updateMany : <document> },
      { replaceOne : <document> },
      { deleteOne : <document> },
      { deleteMany : <document> }
   ]
)

In the default ordered : true state, each operation will be executed in order, from the first operation insertOne to the last operation deleteMany.在默认的ordered:true状态下,每个操作都将按顺序执行,从第一个操作insertOne到最后一个操作deleteMany

If ordered is set to false, operations may be reordered by mongod to increase performance. 如果ordered设置为falsemongod可能会对操作重新排序以提高性能。Applications should not depend on order of operation execution.应用程序不应依赖于操作的执行顺序。

The following code represents an unordered bulkWrite() with six operations:以下代码表示一个无序的bulkWrite(),包含六个操作:

db.collection.bulkWrite(
   [
      { insertOne : <document> },
      { updateOne : <document> },
      { updateMany : <document> },
      { replaceOne : <document> },
      { deleteOne : <document> },
      { deleteMany : <document> }
   ],
   { ordered : false }
)

With ordered : false, the results of the operation may vary. 如果ordered:false,操作结果可能会有所不同。For example, the deleteOne or deleteMany may remove more or fewer documents depending on whether the run before or after the insertOne, updateOne, updateMany, or replaceOne operations.例如,deleteOnedeleteMany可能会删除更多或更少的文档,具体取决于是在insertOneupdateOneupdateMany还是replaceOne操作之前或之后运行。

The number of operations in each group cannot exceed the value of the maxWriteBatchSize of the database. 每个组中的操作数不能超过数据库的maxWriteBatchSize值。As of MongoDB 3.6, this value is 100,000. 截至MongoDB 3.6,该值为100,000This value is shown in the isMaster.maxWriteBatchSize field.此值显示在isMaster.maxWriteBatchSize字段中。

This limit prevents issues with oversized error messages. 此限制可防止出现错误消息过大的问题。If a group exceeds this limit, the client driver divides the group into smaller groups with counts less than or equal to the value of the limit. 如果一个组超过此limit,客户端驱动程序会将该组划分为计数小于或等于该限制值的较小组。For example, with the maxWriteBatchSize value of 100,000, if the queue consists of 200,000 operations, the driver creates 2 groups, each with 100,000 operations.例如,maxWriteBatchSize值为100,000时,如果队列包含200,000个操作,则驱动程序将创建两个组,每个组包含100,000个操作。

Note

The driver only divides the group into smaller groups when using the high-level API. 在使用高级API时,驱动程序仅将组划分为较小的组。If using db.runCommand() directly (for example, when writing a driver), MongoDB throws an error when attempting to execute a write batch which exceeds the limit.如果直接使用db.runCommand()(例如,在编写驱动程序时),MongoDB在尝试执行超出限制的写入批处理时会抛出错误。

Starting in MongoDB 3.6, once the error report for a single batch grows too large, MongoDB truncates all remaining error messages to the empty string. 从MongoDB 3.6开始,一旦单个批次的错误报告变得太大,MongoDB就会将所有剩余的错误消息截断为空字符串。Currently, begins once there are at least 2 error messages with total size greater than 1MB.目前,当至少有2条总大小大于1MB的错误消息时开始。

The sizes and grouping mechanics are internal performance details and are subject to change in future versions.尺寸和分组机制是内部性能细节,在未来版本中可能会发生更改。

Executing an ordered list of operations on a sharded collection will generally be slower than executing an unordered list since with an ordered list, each operation must wait for the previous operation to finish.在分片集合上执行操作的有序列表通常比执行无序列表慢,因为对于有序列表,每个操作都必须等待前一个操作完成。

Capped Collections封顶系列

bulkWrite() write operations have restrictions when used on a capped collection.写入操作在封顶集合上使用时有限制。

updateOne and updateMany throw a WriteError if the update criteria increases the size of the document being modified.如果update条件增加了被修改文档的大小,updateOneupdateMany可能会抛出WriteError

replaceOne throws a WriteError if the replacement document has a larger size than the original document.如果replacement文档的大小大于原始文档,则replaceOne会抛出WriteError

deleteOne and deleteMany throw a WriteError if used on a capped collection.deleteOnedeleteMany如果用于封顶集合,则会抛出WriteError

Error Handling错误处理

db.collection.bulkWrite() throws a BulkWriteError exception on errors (unless the operation is part of a transaction on MongoDB 4.0). db.collection.bulkWrite()在出现错误时抛出BulkWriteError异常(除非该操作是MongoDB 4.0上事务的一部分)。See Error Handling inside Transactions.请参阅内部事务中的错误处理

Excluding Write Concern errors, ordered operations stop after an error, while unordered operations continue to process any remaining write operations in the queue, unless when run inside a transaction. 除了写相关错误,有序操作在错误发生后停止,而无序操作继续处理队列中任何剩余的写操作,除非在事务内部运行。See Error Handling inside Transactions.请参阅内部事务中的错误处理

Write concern errors are displayed in the writeConcernErrors field, while all other errors are displayed in the writeErrors field. 写入问题错误显示在writeConcernErrors字段中,而所有其他错误显示在writeErrors字段中。If an error is encountered, the number of successful write operations are displayed instead of the inserted _id values. 如果遇到错误,将显示成功写入操作的次数,而不是插入的_id值。Ordered operations display the single error encountered while unordered operations display each error in an array.有序操作显示遇到的单个错误,而无序操作显示数组中的每个错误。

Transactions事务

db.collection.bulkWrite() can be used inside multi-document transactions.可以在多文档事务中使用。

Important重要的

In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transactions should not be a replacement for effective schema design. 在大多数情况下,与单文档写入相比,多文档事务会带来更大的性能成本,而多文档事务的可用性不应取代有效的模式设计。For many scenarios, the denormalized data model (embedded documents and arrays) will continue to be optimal for your data and use cases. 对于许多场景,非规范化数据模型(嵌入式文档和数组)将继续适合您的数据和用例。That is, for many scenarios, modeling your data appropriately will minimize the need for multi-document transactions.也就是说,对于许多场景,适当地建模数据将最大限度地减少对多文档事务的需求。

For additional transactions usage considerations (such as runtime limit and oplog size limit), see also Production Considerations.有关其他事务使用注意事项(如运行时限制和oplog大小限制),请参阅生产注意事项

Inserts and Upserts within Transactions事务中的插入和向上插入

For feature compatibility version (fcv) "4.4" and greater, if an insert operation or update operation with upsert: true is run in a transaction against a non-existing collection, the collection is implicitly created.对于功能兼容性版本(fcv)"4.4"及更高版本,如果在事务中针对不存在的集合运行upsert:true的插入操作或更新操作,则会隐式创建集合。

Note

You cannot create new collections in cross-shard write transactions. 不能在跨碎片写入事务中创建新集合。For example, if you write to an existing collection in one shard and implicitly create a collection in a different shard, MongoDB cannot perform both operations in the same transaction.例如,如果在一个碎片中写入现有集合,并在另一个碎片中隐式创建集合,MongoDB无法在同一事务中执行这两个操作。

For fcv "4.2" or less, the collection must already exist for insert and upsert: true operations.对于fcv"4.2"或更低版本,对于insert和upsert:true操作,集合必须已经存在。

Write Concerns and Transactions撰写关注事项和交易记录

Do not explicitly set the write concern for the operation if run in a transaction. 如果在事务中运行,请不要显式设置操作的写入关注点。To use write concern with transactions, see Transactions and Write Concern.要将写关注点用于事务,请参阅事务和写关注点

Error Handling inside Transactions处理内部事务时出错

Starting in MongoDB 4.2, if a db.collection.bulkWrite() operation encounters an error inside a transaction, the method throws a BulkWriteException (same as outside a transaction).从MongoDB 4.2开始,如果db.collection.bulkWrite()操作在事务内部遇到错误,该方法将抛出BulkWriteException(与事务外部相同)。

In 4.0, if the bulkWrite operation encounters an error inside a transaction, the error thrown is not wrapped as a BulkWriteException.在4.0中,如果bulkWrite操作在事务中遇到错误,抛出的错误不会包装为BulkWriteException

Inside a transaction, the first error in a bulk write causes the entire bulk write to fail and aborts the transaction, even if the bulk write is unordered.在事务内部,批量写入中的第一个错误会导致整个批量写入失败并中止事务,即使批量写入是无序的。

Examples示例

Bulk Write Operations批量写入操作

The characters collection in the guidebook database contains the following documents:guidebook数据库中的characters集合包含以下文档:

{ "_id" : 1, "char" : "Brisbane", "class" : "monk", "lvl" : 4 },
{ "_id" : 2, "char" : "Eldon", "class" : "alchemist", "lvl" : 3 },
{ "_id" : 3, "char" : "Meldane", "class" : "ranger", "lvl" : 3 }

The following bulkWrite() performs multiple operations on the collection:以下bulkWrite()对集合执行多个操作:

try {
   db.characters.bulkWrite([
      { insertOne: { "document": { "_id": 4, "char": "Dithras", "class": "barbarian", "lvl": 4 } } },
      { insertOne: { "document": { "_id": 5, "char": "Taeln", "class": "fighter", "lvl": 3 } } },
      { updateOne : {
         "filter" : { "char" : "Eldon" },
         "update" : { $set : { "status" : "Critical Injury" } }
      } },
      { deleteOne : { "filter" : { "char" : "Brisbane"} } },
      { replaceOne : {
         "filter" : { "char" : "Meldane" },
         "replacement" : { "char" : "Tanys", "class" : "oracle", "lvl": 4 }
      } }
   ]);
} catch (e) {
   print(e);
}

The operation returns the following:该操作返回以下内容:

{
   "acknowledged" : true,
   "deletedCount" : 1,
   "insertedCount" : 2,
   "matchedCount" : 2,
   "upsertedCount" : 0,
   "insertedIds" : {
      "0" : 4,
      "1" : 5
   },
   "upsertedIds" : {

   }
}

If the collection had contained a document with "_id" : 5" before executing the bulk write, then when the bulk write is executed, the following duplicate key exception would be thrown for the second insertOne:如果在执行大容量写入之前,集合中包含一个带有"_id" : 5"的文档,那么在执行大容量写入时,将为第二个insertOne引发以下重复键异常:

BulkWriteError({
   "writeErrors" : [
      {
         "index" : 1,
         "code" : 11000,
         "errmsg" : "E11000 duplicate key error collection: guidebook.characters index: _id_ dup key: { _id: 5.0 }",
         "op" : {
            "_id" : 5,
            "char" : "Taeln",
            "class" : "fighter",
            "lvl" : 3
         }
      }
   ],
   "writeConcernErrors" : [ ],
   "nInserted" : 1,
   "nUpserted" : 0,
   "nMatched" : 0,
   "nModified" : 0,
   "nRemoved" : 0,
   "upserted" : [ ]
})

Since ordered is true by default, only the first operation completes successfully. 由于ordered默认为true,因此只有第一个操作成功完成。The rest are not executed. 其余的都没有被执行。Running the bulkWrite() with ordered : false would allow the remaining operations to complete despite the error.使用ordered:false运行bulkWrite()将允许完成剩余的操作,尽管存在错误。

Unordered Bulk Write无序批量写入

The characters collection in the guidebook database contains the following documents:guidebook数据库中的characters集合包含以下文档:

{ "_id" : 1, "char" : "Brisbane", "class" : "monk", "lvl" : 4 },
{ "_id" : 2, "char" : "Eldon", "class" : "alchemist", "lvl" : 3 },
{ "_id" : 3, "char" : "Meldane", "class" : "ranger", "lvl" : 3 }

The following bulkWrite() performs multiple unordered operations on the characters collection. 以下bulkWrite()characters集合执行多个无序操作。Note that one of the insertOne stages has a duplicate _id value:请注意,其中一个insertOne阶段具有重复的_id值:

try {
   db.characters.bulkWrite([
      { insertOne: { "document": { "_id": 4, "char": "Dithras", "class": "barbarian", "lvl": 4 } } },
      { insertOne: { "document": { "_id": 4, "char": "Taeln", "class": "fighter", "lvl": 3 } } },
      { updateOne : {
         "filter" : { "char" : "Eldon" },
         "update" : { $set : { "status" : "Critical Injury" } }
      } },
      { deleteOne : { "filter" : { "char" : "Brisbane"} } },
      { replaceOne : {
         "filter" : { "char" : "Meldane" },
         "replacement" : { "char" : "Tanys", "class" : "oracle", "lvl": 4 }
      } }
   ], { ordered : false } );
} catch (e) {
   print(e);
}

The operation returns the following:该操作返回以下内容:

BulkWriteError({
   "writeErrors" : [
      {
         "index" : 1,
         "code" : 11000,
         "errmsg" : "E11000 duplicate key error collection: guidebook.characters index: _id_ dup key: { _id: 4.0 }",
         "op" : {
            "_id" : 4,
            "char" : "Taeln",
            "class" : "fighter",
            "lvl" : 3
         }
      }
   ],
   "writeConcernErrors" : [ ],
   "nInserted" : 1,
   "nUpserted" : 0,
   "nMatched" : 2,
   "nModified" : 2,
   "nRemoved" : 1,
   "upserted" : [ ]
})

Since this was an unordered operation, the writes remaining in the queue were processed despite the exception.由于这是一个无序操作,因此尽管出现异常,仍会处理队列中剩余的写操作。

Bulk Write with Write Concern带写关注的批量写入

The enemies collection contains the following documents:code>enemies集合包含以下文档:

{ "_id" : 1, "char" : "goblin", "rating" : 1, "encounter" : 0.24 },
{ "_id" : 2, "char" : "hobgoblin", "rating" : 1.5, "encounter" : 0.30 },
{ "_id" : 3, "char" : "ogre", "rating" : 3, "encounter" : 0.2 },
{ "_id" : 4, "char" : "ogre berserker" , "rating" : 3.5, "encounter" : 0.12}

The following bulkWrite() performs multiple operations on the collection using a write concern value of "majority" and timeout value of 100 milliseconds:以下bulkWrite()使用写入关注"majority"超时值100毫秒对集合执行多个操作:

try {
   db.enemies.bulkWrite(
      [
         { updateMany :
            {
               "filter" : { "rating" : { $gte : 3} },
               "update" : { $inc : { "encounter" : 0.1 } }
            },

         },
         { updateMany :
            {
               "filter" : { "rating" : { $lt : 2} },
               "update" : { $inc : { "encounter" : -0.25 } }
            },
         },
         { deleteMany : { "filter" : { "encounter": { $lt : 0 } } } },
         { insertOne :
            {
               "document" :
                  {
                     "_id" :5, "char" : "ogrekin" , "rating" : 2, "encounter" : 0.31
                  }
            }
         }
      ],
      { writeConcern : { w : "majority", wtimeout : 100 } }
   );
} catch (e) {
   print(e);
}

If the total time required for all required nodes in the replica set to acknowledge the write operation is greater than wtimeout, the following writeConcernError is displayed when the wtimeout period has passed.如果副本集中所有必需节点确认写入操作所需的总时间大于wtimeout,则在wtimeout期间结束后,将显示以下writeConcernError

BulkWriteError({
   "writeErrors" : [ ],
   "writeConcernErrors" : [
      {
         "code" : 64,
         "codeName" : "WriteConcernFailed",
         "errmsg" : "waiting for replication timed out",
         "errInfo" : {
            "wtimeout" : true
         }
      },
      {
         "code" : 64,
         "codeName" : "WriteConcernFailed",
         "errmsg" : "waiting for replication timed out",
         "errInfo" : {
            "wtimeout" : true
         }
      },
      {
         "code" : 64,
         "codeName" : "WriteConcernFailed",
         "errmsg" : "waiting for replication timed out",
         "errInfo" : {
            "wtimeout" : true
         }
      }
   ],
   "nInserted" : 1,
   "nUpserted" : 0,
   "nMatched" : 4,
   "nModified" : 4,
   "nRemoved" : 1,
   "upserted" : [ ]
})

The result set shows the operations executed since writeConcernErrors errors are not an indicator that any write operations failed.结果集显示了自writeConcernErrors错误以来执行的操作,这些错误并不表示任何写入操作都失败。