Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

db.collection.insertMany()

在此页面上

  • 定义
  • 兼容性
  • 语法
  • 行为
  • 示例

带驱动程序的 MongoDB

本页面提供 mongosh 方法的相关信息。要查看 MongoDB 驱动程序中的等效方法,请参阅编程语言的相应页面:

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRustScala
db.collection.insertMany()

将多个文档插入到一个集合中。

返回:

文档包含以下内容:

  • 一个acknowledged 布尔值,如果操作在true 写关注(write concern)下运行,则设立为 ;如果禁用写关注(writefalse concern),则设置为

  • 一个 insertedIds 数组,包含每份成功插入的文档的 _id

此方法可用于以下环境中托管的部署:

注意

所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令

insertMany() 方法使用的语法如下:

db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
Parameter
类型
说明

document

文档

要插入到集合中的文档的数组。

writeConcern

文档

可选。表达写关注的文档。省略以使用默认写关注。

如果是在事务中运行,则请勿显式设置此操作的写关注。要将写关注与事务一起使用,请参阅事务和写关注。

ordered

布尔

可选。一个布尔值,指定 mongod 实例应该执行有序插入还是无序插入。默认为 true

对于给定的文档数组,insertMany() 可将该数组中的每个文档插入到相应集合中。

默认情况下,文档会按其提供的顺序插入。

如果 ordered 设置为 true 并且插入失败,则服务器不会继续插入记录。

如果 ordered 设为 false 且插入操作失败,服务器会继续插入记录。文档可按 mongod 重新排序,从而提高性能。如果使用无序 insertMany()应用程序不应依赖插入的顺序。

每组中的操作次数不得超过数据库的 maxWriteBatchSize 值。maxWriteBatchSize 的默认值为 100,000。该值会显示在 hello.maxWriteBatchSize 字段中。

此限制可防止错误消息过大的问题。如果一个群组超过此限制,则客户端驱动程序会将该群组分成计数小于或等于限制值的更小群组。例如,对于 maxWriteBatchSize 值为 100,000 的情况,如果队列由 200,000 个操作组成,则驱动程序将创建 2 个群组,每个群组包含 100,000 个操作。

注意

该驱动程序仅在使用高级 API 时会将上述群组划分为多个更小的群组。如果直接使用 db.runCommand()(例如,在编写驱动程序时),MongoDB 在尝试执行超过限制的写入批处理时会引发错误。

如果单个批处理的错误报告变得过大,MongoDB 会将所有剩余的错误消息截断为空字符串。如果至少存在两条总大小大于 1MB 的错误消息,则会将其截断。

大小和分组机制是内部性能细节,在未来版本中可能会有变化。

在分片集合上执行操作的 ordered 列表通常比执行 unordered 列表慢,因为对于有序列表,每个操作都必须等待前一个操作完成。

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

如果文档未指定 _id 字段,mongod 则会添加 _id 字段并为该文档分配一个唯一 ObjectId()。大多数驱动程序均会创建一个 ObjectId 并插入 _id 字段;如果驱动程序或应用程序未执行上述操作,mongod 则会创建并填充 _id

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

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

插入会引发 BulkWriteError 异常。

不包括写关注错误,有序操作会在出错后停止,而无序操作则会继续处理队列中剩余的写入操作。

写关注错误显示在 writeConcernErrors 字段,所有其他错误则显示在 writeErrors 字段。如果遇到错误,则会显示成功写操作的数量,而不是插入的 _ids 列表。有序操作显示遇到的单个错误,而无序操作则以数组形式显示每个错误。

如果您的集合使用模式验证并将 validationAction 设置为 error ,则插入带有 db.collection.insertMany() 无效文档会引发 writeError 。在 documents 数组中,无效文档前面的文档将写入集合。ordered 字段的值确定是否插入其余有效文档。

db.collection.insertMany() 可以在分布式事务中使用。

重要

在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。

有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项

如果事务不是跨分片写事务,则可以在分布式事务中创建集合和索引。

如果在事务中对不存在的集合指定插入操作,则 MongoDB 会隐式创建该集合。

提示

另请参阅:

如果是在事务中运行,则请勿显式设置此操作的写关注。要将写关注与事务一起使用,请参阅事务和写关注。

如果某操作在已索引字段上插入大量随机数据(例如,哈希索引),插入性能可能会降低。随机数据的批量插入会创建随机索引条目,从而增加索引的大小。如果索引达到需要每次随机插入都访问不同索引条目的大小,则插入操作会导致较高的 WiredTiger 缓存逐出和替换速度。发生这种情况时,索引不再完全位于缓存中,而是在磁盘上更新,这会降低性能。

要提高在已索引字段上批量插入随机数据的性能,可以采用以下两种方法之一:

  • 删除索引,然后在插入随机数据后重新创建该索引。

  • 将数据插入一个空的无索引集合。

批量插入后创建索引会对内存中的数据排序并对所有索引执行有序插入。

如果 db.collection.insertMany() 操作成功插入了一个或多个文档,则该操作会为每个插入的文档在 oplog(操作日志)上添加一个条目。如果操作失败,则该操作不会为 oplog 添加条目。

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

下面的示例使用 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 值特定于运行操作时的设备和时间。因此,您的值可能与示例中的值不同。

以下示例/操作使用 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 ] }

为属于唯一索引的任何键插入重复值(例如 _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,则插入操作将继续处理剩余文档。

以下尝试插入具有 _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" : [ ]
})

虽然包含 item: "medium box"item: "tape" 的文档由于存在重复的 _id 值而未能插入,nInserted 显示其余 5 个文档已插入。

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

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,
"errmsg" : "waiting for replication timed out",
"errInfo" : {
"wtimeout" : true,
"writeConcern" : {
"w" : "majority",
"wtimeout" : 100,
"provenance" : "getLastErrorDefaults"
}
}
})

提示

另请参阅:

后退

db.collection.insert