db.collection.insertMany()

在本页面

Definition

将多个文档插入集合中。

insertMany()方法具有以下语法:

db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)
Parameter Type Description
document document 要插入到集合中的一组文档。
writeConcern document 可选的。表示write concern的文档。省略使用默认的写关注。
ordered boolean 可选的。一个布尔值,指定mongod实例应执行有序插入还是无序插入。默认为true
返回: 包含以下内容的文档:
如果操作以write concernfalse运行,则布尔acknowledgedtrue,如果禁用了写关注
每个成功插入的文档的_id数组

Behaviors

给定一个文档数组,insertMany()将数组中的每个文档插入到集合中。

执行作业

默认情况下,按 Sequences 插入文档。

如果ordered设置为 false,则文档将以无序格式插入,并且可以由mongod重新排序以提高性能。如果使用无序insertMany(),则应用程序不应依赖于插入的 Sequences。

每个组中的操作数不能超过数据库的maxWriteBatchSize的值。从 MongoDB 3.6 开始,此值为100,000。此值显示在isMaster.maxWriteBatchSize字段中。

此限制可防止出现错误消息过多的问题。如果组超过此limit,则 Client 端驱动程序会将组划分为计数小于或等于限制值的较小组。例如,使用100,000maxWriteBatchSize值,如果队列包含200,000个操作,则驱动程序将创建 2 个组,每个组具有100,000个操作。

Note

当使用高级 API 时,驱动程序仅将组划分为较小的组。如果直接使用db.runCommand()(例如,在编写驱动程序时),则 MongoDB 在尝试执行超出限制的写批处理时会引发错误。

从 MongoDB 3.6 开始,一旦单个批次的错误报告变得太大,MongoDB 就会将所有剩余的错误消息截断为空字符串。当前,至少在总大小大于1MB的 2 条错误消息后开始。

大小和分组机制是内部性能的详细信息,将来可能会更改。

在分片集合上执行ordered操作列表通常比执行unordered列表要慢,因为使用有序列表,每个操作必须 await 上一个操作完成。

Collection Creation

如果该集合不存在,则insertMany()在成功写入时创建该集合。

_id Field

如果文档未指定_id字段,则mongod添加_id字段并为文档分配唯一的ObjectId。大多数驱动程序会创建一个 ObjectId 并插入_id字段,但如果驱动程序或应用程序未创建,则mongod将创建并填充_id

如果文档包含_id字段,则_id值在集合中必须唯一,以避免重复的键错误。

Explainability

insertMany()db.collection.explain()不兼容。

请改用insert()

Error Handling

插入引发BulkWriteError异常。

Write Concern个错误外,有序操作在发生错误后停止,而无序操作 continue 处理队列中所有剩余的写操作。

写关注错误显示在writeConcernErrors字段中,而所有其他错误显示在writeErrors字段中。如果遇到错误,将显示成功写入操作的次数,而不是插入的_id 的列表。有序操作显示遇到的单个错误,而无序操作显示数组中的每个错误。

Examples

以下示例将文档插入products集合。

插入多个文档而不指定_id 字段

下面的示例使用db.collection.insertMany()插入不包含_id字段的文档:

try {
   db.products.insertMany( [
      { item: "card", qty: 15 },
      { item: "envelope", qty: 20 },
      { item: "stamps" , qty: 30 }
   ] );
} catch (e) {
   print (e);
}

该操作返回以下文档:

{
   "acknowledged" : true,
   "insertedIds" : [
      ObjectId("562a94d381cb9f1cd6eb0e1a"),
      ObjectId("562a94d381cb9f1cd6eb0e1b"),
      ObjectId("562a94d381cb9f1cd6eb0e1c")
   ]
}

由于文档不包含_id,因此mongod为每个文档创建并添加_id字段,并为其分配唯一的ObjectId值。

ObjectId值特定于机器和运行操作的时间。因此,您的值可能与示例中的值不同。

插入多个指定_id 字段的文档

以下示例/操作使用insertMany()插入包含_id字段的文档。 _id的值在集合中必须唯一,以避免重复的键错误。

try {
   db.products.insertMany( [
      { _id: 10, item: "large box", qty: 20 },
      { _id: 11, item: "small box", qty: 55 },
      { _id: 12, item: "medium box", qty: 30 }
   ] );
} catch (e) {
   print (e);
}

该操作返回以下文档:

{ "acknowledged" : true, "insertedIds" : [ 10, 11, 12 ] }

为属于unique index的任何键(例如_id)插入重复值会引发异常。以下尝试插入具有_id值的文档:

try {
   db.products.insertMany( [
      { _id: 13, item: "envelopes", qty: 60 },
      { _id: 13, item: "stamps", qty: 110 },
      { _id: 14, item: "packing tape", qty: 38 }
   ] );
} catch (e) {
   print (e);
}

由于_id: 13已经存在,将引发以下异常:

BulkWriteError({
   "writeErrors" : [
      {
         "index" : 0,
         "code" : 11000,
         "errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 13.0 }",
         "op" : {
            "_id" : 13,
            "item" : "stamps",
            "qty" : 110
         }
      }
   ],
   "writeConcernErrors" : [ ],
   "nInserted" : 1,
   "nUpserted" : 0,
   "nMatched" : 0,
   "nModified" : 0,
   "nRemoved" : 0,
   "upserted" : [ ]
})

请注意,已插入一个文档:_id: 13的第一个文档将成功插入,而第二个插入将失败。这也将阻止插入队列中剩余的其他文档。

使用orderedfalse,插入操作将 continue 处理所有剩余文档。

Unordered Inserts

以下尝试插入带有_id字段和ordered: false的多个文档。文档数组包含两个具有重复的_id字段的文档。

try {
   db.products.insertMany( [
      { _id: 10, item: "large box", qty: 20 },
      { _id: 11, item: "small box", qty: 55 },
      { _id: 11, item: "medium box", qty: 30 },
      { _id: 12, item: "envelope", qty: 100},
      { _id: 13, item: "stamps", qty: 125 },
      { _id: 13, item: "tape", qty: 20},
      { _id: 14, item: "bubble wrap", qty: 30}
   ], { ordered: false } );
} catch (e) {
   print (e);
}

该操作引发以下异常:

BulkWriteError({
   "writeErrors" : [
      {
         "index" : 2,
         "code" : 11000,
         "errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 11.0 }",
         "op" : {
            "_id" : 11,
            "item" : "medium box",
            "qty" : 30
         }
      },
      {
         "index" : 5,
         "code" : 11000,
         "errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 13.0 }",
         "op" : {
            "_id" : 13,
            "item" : "tape",
            "qty" : 20
         }
      }
   ],
   "writeConcernErrors" : [ ],
   "nInserted" : 5,
   "nUpserted" : 0,
   "nMatched" : 0,
   "nModified" : 0,
   "nRemoved" : 0,
   "upserted" : [ ]
})

由于重复的_id值而无法插入具有item: "medium box"item: "tape"的文档,而nInserted显示剩余的 5 个文档已插入。

使用写问题

给定一个三成员副本集,以下操作指定wmajoritywtimeout100

try {
   db.products.insertMany(
      [
         { _id: 10, item: "large box", qty: 20 },
         { _id: 11, item: "small box", qty: 55 },
         { _id: 12, item: "medium box", qty: 30 }
      ],
      { w: "majority", wtimeout: 100 }
   );
} catch (e) {
   print (e);
}

如果主服务器和至少一个辅助服务器在 100 毫秒内确认每个写操作,则返回:

{
  "acknowledged" : true,
  "insertedIds" : [
     ObjectId("562a94d381cb9f1cd6eb0e1a"),
     ObjectId("562a94d381cb9f1cd6eb0e1b"),
     ObjectId("562a94d381cb9f1cd6eb0e1c")
  ]
}

如果副本集中所有必需节点确认写操作所需的总时间大于wtimeout,则经过wtimeout周期后,将显示以下writeConcernError

该操作返回:

WriteConcernError({
   "code" : 64,
   "errInfo" : {
      "wtimeout" : true
   },
   "errmsg" : "waiting for replication timed out"
})
首页