db.collection.bulkWrite()
在本页面
Definition
db.collection.
bulkWrite
( )- 3.2 版中的新功能。
使用控件执行多个写入操作以执行 Sequences。
bulkWrite()具有以下语法:
db.collection.bulkWrite(
[ <operation 1>, <operation 2>, ... ],
{
writeConcern : <document>,
ordered : <boolean>
}
)
Parameter | Type | Description |
---|---|---|
operations | array | bulkWrite()个写操作的数组。 |
有效操作是:
insertOne
updateOne
updateMany
deleteOne
deleteMany
replaceOne
有关每个操作的用法,请参见Write Operations。
| writeConcern
|文档|可选。表示write concern的文档。忽略使用默认的写关注。
| ordered
|布尔值|可选。一个布尔值,指定mongod实例应执行有序操作还是无序操作执行。默认为true
。
See 执行作业|
返回: | 如果操作以write concern或false 运行,则布尔acknowledged 作为true ,如果禁用了写关注,则为_3.每个写入操作的计数。 一个数组,其中包含每个成功插入或升级后的文档的 _id 。 |
---|
Behavior
bulkWrite()接受一系列写操作并执行每个操作。默认情况下,操作按 Sequences 执行。有关控制写入操作执行 Sequences 的信息,请参见执行作业。
Write Operations
insertOne
将单个文档插入集合中。
See db.collection.insertOne().
db.collection.bulkWrite( [
{ insertOne : { "document" : <document> } }
] )
updateOne 和 updateMany
在版本 3.6 中更改:updateOne
和updateMany
操作增加了对arrayFilters
参数的支持,该参数确定要在数组字段中修改的元素。有关详细信息,请参考db.collection.updateOne()和db.collection.updateMany()。
在版本 3.4 中进行了更改:添加了对collation的支持。有关详情,请参见db.collection.updateOne()和db.collection.updateMany()
updateOne
更新集合中与过滤器匹配的单个文档。如果有多个文档匹配,updateOne
将仅更新* first *匹配的文档。参见db.collection.updateOne()。
db.collection.bulkWrite( [
{ updateOne :
{
"filter" : <document>,
"update" : <document>,
"upsert" : <boolean>,
"collation": <document>,
"arrayFilters": [ <filterdocument1>, ... ]
}
}
] )
updateMany
更新集合中与过滤器匹配的所有文档。参见db.collection.updateMany()。
db.collection.bulkWrite( [
{ updateMany :
{
"filter" : <document>,
"update" : <document>,
"upsert" : <boolean>,
"collation": <document>,
"arrayFilters": [ <filterdocument1>, ... ]
}
}
] )
将query selectors(例如与find()一起使用的__)用于filter
字段。
在update
字段中使用Update Operators,例如$set,$unset或$rename。
默认情况下,upsert
是false
。
replaceOne
在版本 3.4 中进行了更改:添加了对collation的支持。详情请参阅db.collection.replaceOne()
replaceOne
替换集合中与过滤器匹配的**文档。如果多个文档匹配,则replaceOne
将仅替换 first *匹配的文档。参见db.collection.replaceOne()。
db.collection.bulkWrite([
{ replaceOne :
{
"filter" : <document>,
"replacement" : <document>,
"upsert" : <boolean>
}
}
] )
将query selectors(例如与find()一起使用的__)用于filter
字段。
replacement
字段不能包含update operators。
默认情况下,upsert
是false
。
删除一个并删除许多
在版本 3.4 中进行了更改:添加了对collation的支持。有关详情,请参见db.collection.deleteOne()和db.collection.deleteMany()
deleteOne
删除集合中与过滤器匹配的单个文档。如果多个文档匹配,deleteOne
将仅删除* first *匹配的文档。参见db.collection.deleteOne()。
db.collection.bulkWrite([
{ deleteOne : { "filter" : <document> } }
] )
deleteMany
删除集合中与过滤器匹配的所有文档。参见db.collection.deleteMany()。
db.collection.bulkWrite([
{ deleteMany : { "filter" : <document> } }
] )
将query selectors(例如与find()一起使用的__)用于filter
字段。
_id Field
如果文档未指定_id字段,则mongod将添加_id
字段并为文档分配唯一的ObjectId,然后再插入或向上插入它。大多数驱动程序会创建一个 ObjectId 并插入_id
字段,但如果驱动程序或应用程序未创建,则mongod将创建并填充_id
。
如果文档包含_id
字段,则_id
值在集合中必须唯一,以避免重复的键错误。
更新或替换操作不能指定与原始文档不同的_id
值。
执行作业
ordered
参数指定bulkWrite()是否按 Sequences 执行操作。默认情况下,操作按 Sequences 执行。
以下代码代表具有五个操作的bulkWrite()。
db.collection.bulkWrite(
[
{ insertOne : <document> },
{ updateOne : <document> },
{ updateMany : <document> },
{ replaceOne : <document> },
{ deleteOne : <document> },
{ deleteMany : <document> }
]
)
在默认的ordered : true
状态下,将从第一个操作insertOne
到最后一个操作deleteMany
依次执行每个操作。
如果ordered
设置为 false,则mongod可以将操作重新排序以提高性能。应用程序不应依赖于操作执行的 Sequences。
以下代码表示具有六个操作的无序bulkWrite():
db.collection.bulkWrite(
[
{ insertOne : <document> },
{ updateOne : <document> },
{ updateMany : <document> },
{ replaceOne : <document> },
{ deleteOne : <document> },
{ deleteMany : <document> }
],
{ ordered : false }
)
使用ordered : false
,操作结果可能会有所不同。例如,根据在insertOne
,updateOne
,updateMany
或replaceOne
操作之前还是之后运行,deleteOne
或deleteMany
可能会删除更多或更少的文档。
每个组中的操作数不能超过数据库的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 上一个操作完成。
Capped Collections
当在capped collection上使用bulkWrite()时,写入操作会受到限制。
如果update
标准增加了要修改的文档的大小,则updateOne
和updateMany
抛出WriteError
。
如果replacement
文档的大小比原始文档大,则replaceOne
抛出WriteError
。
如果用于上限集合,则deleteOne
和deleteMany
抛出WriteError
。
Error Handling
bulkWrite()引发BulkWriteError
错误。
除Write Concern个错误外,有序操作在发生错误后停止,而无序操作 continue 处理队列中所有剩余的写操作。
写关注错误显示在writeConcernErrors
字段中,而所有其他错误显示在writeErrors
字段中。如果遇到错误,将显示成功写入操作的次数,而不是插入的_id
值。有序操作显示遇到的单个错误,而无序操作显示数组中的每个错误。
Examples
批量写入操作
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 }
以下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" : {
}
}
如果集合在执行批量写入之前包含带有"_id" : 5"
的文档,则在执行批量写入时,将为第二个 insertOne 抛出以下重复键异常:
BulkWriteError({
"writeErrors" : [
{
"index" : 1,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: guidebook.characters index: _id_ dup key: { : 5.0 }",
"op" : {
"_id" : 5,
"char" : "Taeln",
"class" : "fighter",
"lvl" : 3
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 1,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
由于ordered
默认为 true,因此仅第一个操作成功完成。其余的不执行。使用ordered : false
运行bulkWrite()将允许其余操作完成,尽管出现错误。
无序批量写入
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 }
以下bulkWrite()对characters
集合执行多个unordered
操作。请注意,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);
}
该操作返回以下内容:
BulkWriteError({
"writeErrors" : [
{
"index" : 1,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: guidebook.characters index: _id_ dup key: { : 4.0 }",
"op" : {
"_id" : 4,
"char" : "Taeln",
"class" : "fighter",
"lvl" : 3
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 1,
"nUpserted" : 0,
"nMatched" : 2,
"nModified" : 2,
"nRemoved" : 1,
"upserted" : [ ]
})
由于这是unordered
操作,因此尽管有异常,但仍处理了队列中剩余的写入。
具有写问题的批量写
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}
以下bulkWrite()使用"majority"
的write concern值和 100 毫秒的timeout值对集合执行多项操作:
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);
}
如果副本集中所有必需节点确认写操作所需的总时间大于wtimeout
,则经过wtimeout
周期后,将显示以下writeConcernError
。
BulkWriteError({
"writeErrors" : [ ],
"writeConcernErrors" : [
{
"code" : 64,
"codeName" : "WriteConcernFailed",
"errInfo" : {
"wtimeout" : true
},
"errmsg" : "waiting for replication timed out"
},
{
"code" : 64,
"codeName" : "WriteConcernFailed",
"errInfo" : {
"wtimeout" : true
},
"errmsg" : "waiting for replication timed out"
},
{
"code" : 64,
"codeName" : "WriteConcernFailed",
"errInfo" : {
"wtimeout" : true
},
"errmsg" : "waiting for replication timed out"
}
],
"nInserted" : 1,
"nUpserted" : 0,
"nMatched" : 4,
"nModified" : 4,
"nRemoved" : 1,
"upserted" : [ ]
})
结果集显示执行的操作,因为writeConcernErrors
错误不是*任何写入操作失败的指示。