文档菜单
文档首页
/
MongoDB 手册
/ / /

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索引,必须与ns字段中的命名空间ID索引匹配,该索引位于nsInfo数组中。索引从0开始。
document
document
必需
要插入到集合中的文档。
update
整数
必需
更新操作的命名空间ID索引,必须与ns字段中的命名空间ID索引匹配,该索引位于nsInfo数组中。索引从0开始。
filter
document
可选
查询选择器,用于限制更新或删除操作的文档。
updateMods
document
可选

要在集合上执行的操作。您可以选择以下之一

arrayFilters
文档数组
可选

用于指定要修改的文档的过滤文档数组,该文档位于数组字段的更新操作中。

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

multi
布尔值
可选

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

默认为false

hint
document
可选
用于文档filter索引。如果索引不存在,则更新操作返回错误。
constants
document
可选
用于聚合管道自定义更新的常量。
collation
document
可选
更新或删除操作的排序规则
delete
整数
必需
删除操作的命名空间ID索引,必须与ns字段中的命名空间ID索引匹配,该索引位于nsInfo数组中。索引从0开始。
ns
字符串
必需
操作所在的命名空间(数据库和集合)。在ops中将每个操作的命名空间ID索引设置为与ns中匹配的命名空间数组索引。索引从0开始。
collectionUUID
字符串
可选
UUID十六进制值,指定操作的集合。
encryptionInformation
document
可选
操作的信息架构和令牌。有关详细信息,请参阅加密架构。
有序
布尔值
可选

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

有序操作按顺序运行。如果发生错误,则取消剩余操作。

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

默认值为true

bypassDocumentValidation
布尔值
可选

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

默认为false

comment
字符串
可选

可选。用户提供的注释,用于附加到此命令。一旦设置,此注释将出现在以下位置的此命令记录旁边

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

let
document
可选
包含要在此操作中引用的常量的文档。有关let示例,请参阅let选项或c字段中使用变量let中使用变量。
errorsOnly
布尔值
可选

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

默认为false

cursor batchSize
整数
可选
游标批量大小用于bulkWrite命令返回的结果。有关详细信息,请参阅cursor.batchSize()
writeConcern
字符串
可选
写入关注点。省略以使用服务器默认值。

命令返回包含这些字段的文档

字段
类型
描述
光标
document
带有命令结果的光标。
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,则更新或删除操作更新或删除所有匹配的文档。如果为false,则操作更新或删除第一个匹配的文档。有关多文档事务的详细信息,请参阅事务。

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

您可以使用带有可重试写入和将multi字段设置为truebulkWrite插入操作。

您可以使用将multi字段设置为truebulkWrite更新和删除操作。但是,您不能同时使用将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