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

bulkWrite

在此页面上

  • 定义
  • 语法
  • 命令字段
  • 输出
  • 行为
  • 示例
  • 了解详情
bulkWrite

8.0版本新增

从MongoDB 8.0开始,您可以使用新的 bulkWrite命令在一个请求中对多个集合执行多次插入、更新和删除操作。 现有的 db.collection.bulkWrite()方法仅允许您在一个请求中修改一个集合。

要在bulkWrite命令中指定每个集合,请使用命名空间(数据库和集合名称)。

该命令的语法如下:

db.adminCommand( {
bulkWrite: 1,
// Include the insert, update, and delete operations
// in the ops array
ops: [
{
insert: <integer>, // Namespace ID index for insert operation.
// Must match a namespace ID index in
// ns specified later in the nsInfo array.
document: <document>
},
{
update: <integer>, // Namespace ID index for update operation
filter: <document>,
updateMods: <document>,
arrayFilters: [ <filterDocument0>, <filterDocument1>, ... ],
multi: <bolean>,
hint: <document>,
constants: <document>,
collation: <document>
},
{
delete: <integer>, // Namespace ID index for delete operation
filter: <document>,
multi: <boolean>,
hint: <document>,
collation: <document>
},
...
// Additional insert, update, and delete operations in any order
...
],
// Include the namespaces with collections to modify
// in the nsInfo array. You can add multiple namespaces here.
nsInfo: [
{
ns: <string>, // Namespace (database and collection name) to modify.
// Each operation namespace ID index
// specified in the earlier ops array must
// match a namespace ID index here.
collectionUUID: <string>,
encryptionInformation: <document>
},
...
// Additional namespaces
...
],
// Additional fields
ordered: <boolean>,
bypassDocumentValidation: <boolean>,
comment: <string>,
let: <document>,
errorsOnly: <boolean>,
cursor: { batchSize: <integer> },
writeConcern: <string>
} )

在命令语法中,您可以指定多个:

  • ops大量中以任意顺序执行插入、更新和删除操作。

  • nsInfo大量中操作的命名空间。 要将操作与命名空间匹配,请使用相同的命名空间ID索引。 索引从0开始。 您可以使用分片的集合。

该命令接受以下字段:

字段
类型
必要性
说明

insert

整型

必需

插入操作的命名空间ID索引,必须与nsInfo大量的ns字段中的命名空间ID索引匹配。 索引从0开始。

document

文档

必需

要插入到集合中的文档。

update

整型

必需

更新操作的命名空间ID索引,必须与nsInfo大量的ns字段中的命名空间ID索引匹配。 索引从0开始。

filter

文档

Optional

查询选择器,用于限制进行更新或删除操作的文档。

updateMods

文档

Optional

对集合执行的更新操作。 您可以指定以下之一:

arrayFilters

文档数组

Optional

过滤文档数组,指定针对大量字段的更新操作要修改的文档。

有关详细信息,请参阅使用arrayFilters进行数组更新操作。

multi

布尔

Optional

如果multi字段为true ,则更新或删除操作将更新或删除与文档filter匹配的所有文档。 如果为false ,则操作更新或删除与文档filter匹配的第一个文档。 有关多文档事务的详细信息,请参阅事务。

默认值为 false

hint

文档

Optional

用于文档filter索引。 如果索引不存在,更新操作将返回错误。

constants

文档

Optional

用于聚合管道自定义更新的常量。

collation

文档

Optional

更新或删除操作的排序规则

delete

整型

必需

删除操作的命名空间ID索引,必须与nsInfo大量的ns字段中的命名空间ID索引匹配。 索引从0开始。

ns

字符串

必需

操作的命名空间(数据库和集合)。 将ops中每个操作的命名空间ID索引设置为ns中匹配的命名空间大量索引。 索引从0开始。

collectionUUID

字符串

Optional

指定操作集合的UUID十六进制值。

encryptionInformation

文档

Optional

操作的加密信息模式和令牌。 有关详细信息,请参阅加密模式。

ordered

布尔

Optional

如果true ,则执行有序操作。 否则,执行无序操作。

有序操作会串行运行。 如果发生错误,将取消所有剩余操作。

无序操作并行运行。 如果发生错误,则运行剩余的所有语句。 服务器可以对这些操作重新排序,以提高性能。 因此,您的应用程序不应依赖于操作的执行顺序。

默认值为 true

bypassDocumentValidation

布尔

Optional

如果为true ,则操作将绕过文档验证规则。 如果为false ,则文档必须有效。

默认值为 false

comment

字符串

Optional

可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:

注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。

let

文档

Optional

包含要在操作中引用的常量列表的文档。 有关let示例,请参阅let选项或c字段中使用变量以及在let中使用变量。

errorsOnly

布尔

Optional

如果为true ,则该操作仅返回错误并忽略其他输出。

默认值为 false

cursor batchSize

整型

Optional

bulkWrite命令返回结果的游标批处理大小。 有关详细信息,请参阅cursor.batchSize()

writeConcern

字符串

Optional

写入操作的关注点。 省略使用服务器默认。

该命令返回包含以下字段的文档:

字段
类型
说明

cursor

文档

游标带有命令结果。

cursor.id

整型

游标标识符。

cursor.firstBatch

文档数组

操作结果。

cursor.firstBatch.ok

整型

1 表示操作成功。 否则为0

cursor.firstBatch.idx

整型

操作索引号,对应于ops大量中的操作。 第一个操作的idx值为0

cursor.firstBatch.code

整型

错误的代码号。

cursor.firstBatch.errmsg

字符串

错误描述。

cursor.firstBatch.keyPattern

字符串

文档索引键规范是否存在错误。

cursor.firstBatch.keyValue

字符串

发生错误的文档索引键值。

cursor.firstBatch.n

整型

受操作影响的文档总数。

cursor.firstBatch.nModified

整型

更新操作修改的文档数量。

nErrors

整型

bulkWrite命令的错误数。

nInserted

整型

插入的文档数。

nMatched

整型

匹配的文档数量。

nModified

整型

已修改文档的数量。

nUpserted

整型

已更新或插入的文档数量。

nDeleted

整型

已删除文档的数量。

ok

整型

1 表示bulkWrite命令成功。 否则为0

注意

输出字段可能会有所不同,具体取决于您在bulkWrite命令中运行的操作。

本部分介绍bulkWrite命令行为。

如果multi字段为true ,则更新或删除操作将更新或删除与文档filter匹配的所有文档。 如果为false ,则操作更新或删除与文档filter匹配的第一个文档。 有关多文档事务的详细信息,请参阅事务。

要启用重试写入,请参阅可重试写入。

您可以使用具有可重试写入功能的bulkWrite插入操作,并将multi字段设立为true

您可以使用bulkWrite更新和删除操作,并将multi字段设立为true 。 但是,在将multi设立为true和可重试写入的情况下,您无法使用更新或删除操作。

如果将现有的插入、更新和删除命令重写为bulkWrite命令设立errorsOnly设置为true ,则bulkWrite命令具有与现有命令相似的性能。 如果设立errorsOnly设置为false ,性能会变差。

此外,如果您有如下命令序列:

insert
update
delete

如果将这些命令替换为以下示例片段,则无论其他选项如何,使用以下片段的命令都会更快:

{
bulkWrite: 0,
ops: [
insert,
update,
delete
]
}

大部分性能改进是由于网络延迟造成的,网络延迟因实施而异,但示例总是速度更快。

本部分包含bulkWrite命令示例。

以下bulkWrite示例修改了单个命名空间:

1

运行:

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )
2

运行以下bulkWrite命令以对pizzas集合执行插入、更新和删除操作:

db.adminCommand( {
bulkWrite: 1,
// The ops array contains the insert, update, and delete
// operations.
ops: [
// Specify the namespace ID index immediately after
// the insert, update, and delete text.
// For example, "insert: 0" specifies the 0 namespace ID index,
// which is the "test.pizzas" namespace in nsInfo at the end
// of the example.
// Insert a pizza.
{ insert: 0, document: { _id: 4, type: "sausage",
size: "small", price: 12 } },
// Update the price for medium pizzas.
{ update: 0, filter: { size: "medium" },
updateMods: { $set: { price: 15 } } },
// Delete the pizza with an _id of 2.
{ delete: 0, filter: { _id: 2 } }
],
// The nsInfo array contains the namespace to apply the
// previous operations to.
nsInfo: [
{ ns: "test.pizzas" } // Namespace ID index is 0.
]
} )

pizzas集合位于默认的test数据库中,因此ns命名空间为"test.pizzas" 。 命名空间ID索引为0 ,它在ops大量中的插入、更新和删除操作的第一个字段中设立。

3

以下bulkWrite示例输出包含各个ok: 1字段和nErrors: 0 ,表示所有操作均已成功:

{
cursor: {
id: Long('0'),
firstBatch: [
{ ok: 1, idx: 0, n: 1 },
{ ok: 1, idx: 1, n: 1, nModified: 1 },
{ ok: 1, idx: 2, n: 1 }
],
ns: 'admin.$cmd.bulkWrite'
},
nErrors: 0,
nInserted: 1,
nMatched: 1,
nModified: 1,
nUpserted: 0,
nDeleted: 1,
ok: 1
}

有关输出字段的详细信息,请参阅前面的输出部分。

您可以在bulkWrite命令中指定多个命名空间。

以下bulkWrite示例包含针对两个命名空间的插入、更新和删除操作:

1

如果test数据库中已有pizzas集合,请先使用db.collection.drop()方法将其删除,然后运行:

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )
2

运行:

db.pizzaOrders.insertMany( [
{ _id: 0, type: "pepperoni", number: 5,
orderDate: new Date( "2023-01-15T12:00:00Z" ) },
{ _id: 1, type: "cheese", number: 15,
orderDate: new Date( "2023-01-23T11:12:32Z" ) },
{ _id: 2, type: "vegan", number: 20,
orderDate: new Date( "2023-03-20T10:01:12Z" ) }
] )
3

运行以下bulkWrite命令,对示例集合执行插入、更新和删除操作:

db.adminCommand( {
bulkWrite: 1,
// The ops array contains the insert, update, and delete
// operations.
ops: [
// Specify the namespace ID indexes immediately after
// the insert, update, and delete. For example, "insert: 0"
// specifies the 0 namespace ID index, which is the "test.pizzas"
// namespace. And, "insert: 1" specifies "test.pizzaOrders".
// Insert pizzas.
// Namespace ID is 0 for "test.pizzas", which
// is specified as "insert: 0".
{ insert: 0, document: { _id: 5, type: "sausage",
size: "small", price: 12 } },
{ insert: 0, document: { _id: 6, type: "vegan cheese",
size: "large", price: 25 } },
// Update the price for cheese pizzas.
{ update: 0, filter: { type: "cheese" },
updateMods: { $set: { price: 15 } } },
// Delete pizzas with a price less than 7.
{ delete: 0, filter: { price: { $lt: 7 } } },
// Insert pizza orders.
// Namespace ID is 1 for "test.pizzaOrders".
{ insert: 1, document: { _id: 3, type: "sausage", number: 7,
orderDate: new Date( "2023-04-15T12:02:15Z" ) } },
{ insert: 1, document: { _id: 4, type: "vegan", number: 16,
orderDate: new Date( "2023-05-12T11:03:11Z" ) } },
// Update the number of pizza orders for cheese pizzas.
{ update: 1, filter: { type: "cheese" },
updateMods: { $set: { number: 50 } } },
// Delete the pizza order with an _id of 2.
{ delete: 1, filter: { _id: 2 } },
// Delete pizza orders placed before March 15, 2023.
{ delete: 1, filter: { orderDate:
{ $lte: ISODate( "2023-03-15T00:00:00Z" ) } } }
],
// Namespaces
nsInfo: [
{ ns: "test.pizzas" }, // Namespace ID index is 0.
{ ns: "test.pizzaOrders" } // Namespace ID index is 1.
]
} )
4

以下bulkWrite示例输出表示操作成功:

{
cursor: {
id: Long('0'),
firstBatch: [
{ ok: 1, idx: 0, n: 1 },
{ ok: 1, idx: 1, n: 1 },
{ ok: 1, idx: 2, n: 1, nModified: 1 },
{ ok: 1, idx: 3, n: 1 },
{ ok: 1, idx: 4, n: 1 },
{ ok: 1, idx: 5, n: 1 },
{ ok: 1, idx: 6, n: 1, nModified: 1 },
{ ok: 1, idx: 7, n: 1 },
{ ok: 1, idx: 8, n: 1 }
],
ns: 'admin.$cmd.bulkWrite'
},
nErrors: 0,
nInserted: 4,
nMatched: 2,
nModified: 2,
nUpserted: 0,
nDeleted: 3,
ok: 1
}

以下bulkWrite示例包含出现错误的操作和不更改任何文档的操作:

1

如果test数据库中已有pizzas集合,请先使用db.collection.drop()方法将其删除,然后运行:

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )
2

运行以下bulkWrite命令以对pizzas集合执行插入、更新和删除操作:

db.adminCommand( {
bulkWrite: 1,
// The ops array contains the insert, update, and delete
// operations.
ops: [
// The namespace ID indexes are specified immediately after
// the insert, update, and delete text.
// For example, "insert: 0" specifies the 0 namespace ID index,
// which is the "test.pizzas" namespace in nsInfo.
// Attempt to add a duplicate document with an
// _id of 1, which already exists and causes an error.
{ insert: 0, document: { _id: 1, type: "tomato",
size: "small", price: 12 } },
// Attempt to add another duplicate document.
{ insert: 0, document: { _id: 2, type: "pepper",
size: "small", price: 12 } },
// Attempt to change the price for extra large pizzas,
// which don't exist. This doesn't cause an error but
// doesn't update any documents.
{ update: 0, filter: { size: "extra large" },
updateMods: { $set: { price: 15 } } },
// Attempt to remove a document that doesn't exist.
// This doesn't cause an error but doesn't delete any documents.
{ delete: 0, filter: { _id: 8 } }
],
// The nsInfo array contains the namespace to apply the
// previous operations to.
nsInfo: [
{ ns: "test.pizzas" } // Namespace ID index is 0.
],
// Set the ordered field to false to run the remaining operations
// after an operation returns an error.
ordered: false
} )
3

以下bulkWrite示例输出显示了这些错误:

{
cursor: {
id: Long("0"),
firstBatch: [
{
ok: 0,
idx: 0,
code: 11000,
errmsg: 'E11000 duplicate key error collection:
test.pizzas index: _id_ dup key: { _id: 1 }',
keyPattern: { _id: 1 },
keyValue: { _id: 1 },
n: 0
},
{
ok: 0,
idx: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection:
test.pizzas index: _id_ dup key: { _id: 2 }',
keyPattern: { _id: 1 },
keyValue: { _id: 2 },
n: 0
},
{ ok: 1, idx: 2, n: 0, nModified: 0 },
{ ok: 1, idx: 3, n: 0 }
],
ns: 'admin.$cmd.bulkWrite'
},
nErrors: 2,
nInserted: 0,
nMatched: 0,
nModified: 0,
nUpserted: 0,
nDeleted: 0,
ok: 1
}

有关输出字段的详细信息,包括错误代码和消息,请参阅前面的输出部分。

以下bulkWrite示例将errorsOnly设置为true以仅显示错误输出:

1

如果test数据库中已有pizzas集合,请先使用db.collection.drop()方法将其删除,然后运行:

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )
2

运行以下bulkWrite命令,对pizzas集合执行插入、更新和删除操作,其中errorsOnly设立为true

db.adminCommand( {
bulkWrite: 1,
// The ops array contains the insert, update, and delete
// operations.
ops: [
// The namespace ID indexes are specified immediately after
// the insert, update, and delete text.
// For example, "insert: 0" specifies the 0 namespace ID index,
// which is the "test.pizzas" namespace in nsInfo.
// Attempt to add a duplicate document with an
// _id of 1, which already exists and causes an error.
{ insert: 0, document: { _id: 1, type: "tomato",
size: "small", price: 12 } },
// Attempt to add another duplicate document.
{ insert: 0, document: { _id: 2, type: "pepper",
size: "small", price: 12 } },
// Attempt to change the price for extra large pizzas,
// which don't exist. This doesn't cause an error but
// doesn't update any documents.
{ update: 0, filter: { size: "extra large" },
updateMods: { $set: { price: 15 } } },
// Attempt to remove a document that doesn't exist.
// This doesn't cause an error but doesn't delete any documents.
{ delete: 0, filter: { _id: 8 } }
],
// The nsInfo array contains the namespace to apply the
// previous operations to.
nsInfo: [
{ ns: "test.pizzas" } // Namespace ID index is 0.
],
// Set the ordered field to false to run the remaining operations
// after an operation returns an error.
ordered: false,
// Set the errorsOnly field to true to only output the errors.
errorsOnly: true
} )
3

以下bulkWrite示例输出显示了这些错误:

{
cursor: {
id: Long("0"),
firstBatch: [
{
ok: 0,
idx: 0,
code: 11000,
errmsg: 'E11000 duplicate key error collection:
test.pizzas index: _id_ dup key: { _id: 1 }',
keyPattern: { _id: 1 },
keyValue: { _id: 1 },
n: 0
},
{
ok: 0,
idx: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection:
test.pizzas index: _id_ dup key: { _id: 2 }',
keyPattern: { _id: 1 },
keyValue: { _id: 2 },
n: 0
},
],
ns: 'admin.$cmd.bulkWrite'
},
nErrors: 2,
nInserted: 0,
nMatched: 0,
nModified: 0,
nUpserted: 0,
nDeleted: 0,
ok: 1
}

后退

autoCompact