概述

MongoDB提供了客户端执行批量写操作的能力. 批量写操作影响单一集合. MongoDB允许应用程序决定歌可接受的批量操作确认请求等级.

New in version 3.2.

 db.collection.bulkWrite() 提供了批量执行新增、更新和删除的能力 . MongoDB还支持通过db.collection.insertMany()方法批量新增。 

有序与无序操作

批量写操作可以是有序或无序;

关于有序列表的操作, MongoDB 执行串行操作,如果写操作的某个处理过程发生错误,MongoDB将返回但剩下的列表不会执行,查看 ordered Bulk Write

关于无序列表的操作,MongoDB 可以按并行操作,但这种行为没有保证.如果写操作的某个处理过程发生错误, MongoDB 将继续处理剩下的列表. 查查 Unordered Bulk Write.

由于有序列表的操作需要等待之前的操作完成,后面的操作才能继续,所以在分片集合上执行有序列表的操作通常比单一无序列表的操作速度要慢;

默认情况下, bulkWrite() 执行有序操作. 若要执行无序列表操作,请在文档选项中设置 ordered:false 

查看 Execution of Operations

bulkWrite() 方法

bulkWrite()支持以下写操作:

每一个写操作都传入一个数组中包含文档的参数给 bulkWrite() .

示例, 以下执行多个写入操作:

 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 }

以下 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);
}

该操作返回如下:

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

   }
}

更多示例, 查看 bulkWrite() Examples

关于分片集合的批量新增的策略

大批量插入操作(包括初始数据插入或常规数据导入)会影响分片集群性能。对于批量插入,考虑以下策略::

预先分割集合

如果分片集合是空的,那么集合只有一个初始化块,它属于一个单一分片。 MongoDB必须花时间接收数据,创建分割,分发分块到可用分片上,为了避免性能损坏,你可以在分发分割块前预分割集合;.

对 mongos无序写入

 提高对分片集合的写性能,使用 bulkWrite() 的选 项参数 ordered设置为falsemongos 可以试图对多分片同时写入. 对于空集合, 首先要预分割来描述分片集群的分割块的分发.

Avoid Monotonic Throttling

If your shard key increases monotonically during an insert, then all inserted data goes to the last chunk in the collection, which will always end up on a single shard. Therefore, the insert capacity of the cluster will never exceed the insert capacity of that single shard.