On this page
db.collection.insertMany()
在本页面
Definition
db.collection.
insertMany
( )- 3.2 版中的新功能。
将多个文档插入集合中。
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 concern或 false 运行,则布尔acknowledged 为true ,如果禁用了写关注每个成功插入的文档的 _id 数组 |
---|
Behaviors
给定一个文档数组,insertMany()将数组中的每个文档插入到集合中。
执行作业
默认情况下,按 Sequences 插入文档。
如果ordered
设置为 false,则文档将以无序格式插入,并且可以由mongod重新排序以提高性能。如果使用无序insertMany(),则应用程序不应依赖于插入的 Sequences。
每个组中的操作数不能超过数据库的maxWriteBatchSize的值。从 MongoDB 3.6 开始,此值为100,000
。此值显示在isMaster.maxWriteBatchSize字段中。
此限制可防止出现错误消息过多的问题。如果组超过此limit
,则 Client 端驱动程序会将组划分为计数小于或等于限制值的较小组。例如,使用100,000
的maxWriteBatchSize
值,如果队列包含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
的第一个文档将成功插入,而第二个插入将失败。这也将阻止插入队列中剩余的其他文档。
使用ordered
到false
,插入操作将 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 个文档已插入。
使用写问题
给定一个三成员副本集,以下操作指定w
的majority
和wtimeout
的100
:
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"
})