Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs 菜单

批量操作

在本指南中,您可以了解如何使用 Node.js 驱动程序执行批量操作。批量操作有助于减少对服务器的调用次数。您可以在一次执行多个操作,而不是为每个操作发送请求。

提示

要学习;了解有关批量操作的更多信息,请参阅MongoDB Server手册中的批量写入操作

您可以使用批量操作对集合执行多个写入操作。您还可以从客户端运行批量操作,这样就可以跨多个命名空间执行批量写入。在MongoDB中,命名空间由数据库名称和集合名称组成,格式为 <database>.<collection>

本指南包括以下部分:

  • 批量插入操作描述了如何在集合或客户端上执行批量插入操作。

  • 批量替换操作描述了如何在集合或客户端上执行批量替换操作。

  • 批量更新操作描述了如何在集合或客户端上执行批量更新操作。

  • 批量删除操作描述了如何在集合或客户端上执行批量删除操作。

  • 返回类型描述了批量写入操作产生的返回对象。

  • 处理异常描述了批量写入操作中的任何操作失败时发生的异常。

  • 其他信息提供了指向本指南中提及的类型和方法的资源和API文档的链接。

重要

服务器和驱动程序版本要求

集合级批量写入操作需要以下版本:

  • MongoDB Server 3.2 或更高版本

  • Node.js驱动程序版本 3.6 或更高版本

客户端级批量写入操作需要以下版本:

  • MongoDB Server 8.0 或更高版本

  • Node.js驱动程序版本 6.10 或更高版本

The examples in this guide use the movies and users collections in the sample_mflix database, which is included in the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the MongoDB Get Started guide.

要执行批量插入操作,请为要插入的每个文档创建批量操作模型。然后,将这些模型的列表传递给 bulkWrite() 方法。

本节介绍如何执行以下类型的批量操作:

要对集合执行批量插入操作,请为每个操作创建一个 InsertOneModel。然后,对集合调用 bulkWrite() 方法,并将模型大量作为参数传递。要创建 InsertOneModel,请指定模型的 document字段并将其设立为要插入的文档。

此示例将执行以下动作:

  1. 在大量中指定两个 InsertOneModel 实例。每个 InsertOneModel 代表一个要插入到 sample_mflix数据库的 movies集合中的文档。

  2. movies集合上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印插入文档的数量。

const insertModels = [{
insertOne: {
document: {
title: "The Favourite",
year: 2018,
rated: "R",
released: "2018-12-21"
}
}
}, {
insertOne: {
document: {
title: "I, Tonya",
year: 2017,
rated: "R",
released: "2017-12-08"
}
}
}];
const insertResult = await movies.bulkWrite(insertModels);
console.log(`Inserted documents: ${insertResult.insertedCount}`);
Inserted documents: 2

要跨多个集合或数据库执行批量插入操作,请为每个操作创建一个 ClientBulkWriteModel。然后,在客户端上调用 bulkWrite() 方法并将模型大量作为参数传递。

下表描述了您可以在 ClientBulkWriteModel 中设立以指定插入操作的字段:

字段
说明

namespace

要在其中插入文档的命名空间空间。
类型:String

name

要执行的操作。对于插入操作,请将此字段设立为 "insertOne"
类型:String

document

要插入的文档。
类型:Document

此示例将执行以下动作:

  1. 在一个大量中指定三个 ClientBulkWriteModel 实例。前两个模型表示要插入到 movies集合中的文档,最后一个模型表示要插入到 users集合中的文档。

  2. 在客户端上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印插入文档的数量。

const clientInserts = [{
namespace: "sample_mflix.movies",
name: "insertOne",
document: {
title: "The Favourite",
year: 2018,
rated: "R",
released: "2018-12-21"
}
}, {
namespace: "sample_mflix.movies",
name: "insertOne",
document: {
title: "I, Tonya",
year: 2017,
rated: "R",
released: "2017-12-08"
}
}, {
namespace: "sample_mflix.users",
name: "insertOne",
document: {
name: "Brian Schwartz",
email: "bschwartz@example.com"
}
}];
const clientInsertRes = await client.bulkWrite(clientInserts);
console.log(`Inserted documents: ${clientInsertRes.insertedCount}`);
Inserted documents: 3

要执行批量替换操作,请为要替换的每个文档创建批量操作模型。然后,将这些模型的列表传递给 bulkWrite() 方法。

本节介绍如何执行以下类型的批量操作:

要对集合执行批量替换操作,请为每个操作创建一个 ReplaceOneModel。然后,对集合调用 bulkWrite() 方法,并将模型大量作为参数传递。

下表描述了您可以在 ReplaceOneModel 中设立的字段:

字段
说明

filter

与要替换的文档匹配的过滤器。
类型:Document

replacement

替换文档。
类型:Document

collation

(可选)对结果进行排序时使用的排序规则。要学习有关排序规则的更多信息,请参阅 排序规则部分的配置 CRUD 操作指南。
类型:StringObject

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 用于查询优化的索引 指南。
类型:Bson

upsert

(可选)如果没有文档与过滤器匹配,是否创建新文档。
默认下,此字段设立为 false
类型:Boolean

此示例将执行以下动作:

  1. 在大量中指定两个 ReplaceOneModel 实例。 ReplaceOneModel 实例包含替换 movies集合中表示电影的文档的指令。

  2. movies集合上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印已修改文档的数量。

const replaceOperations = [{
replaceOne: {
filter: {
title: "The Dark Knight"
},
replacement: {
title: "The Dark Knight Rises",
year: 2012,
rating: "PG-13"
},
upsert: false
}
}, {
replaceOne: {
filter: {
title: "Inception"
},
replacement: {
title: "Inception Reloaded",
year: 2010,
rating: "PG-13"
},
upsert: false
}
}];
const replaceResult = await movies.bulkWrite(replaceOperations);
console.log(`Modified documents: ${replaceResult.modifiedCount}`);
Modified documents: 2

要跨多个集合或数据库执行批量替换操作,请为每个操作创建一个 ClientBulkWriteModel。然后,在客户端上调用 bulkWrite() 方法并将模型大量作为参数传递。

下表描述了您可以在 ClientBulkWriteModel 中设立以指定替换操作的字段:

字段
说明

namespace

要替换文档的命名空间空间。
类型:String

name

要执行的操作。对于替换操作,请将此字段设立为 "replaceOne"
类型:String

filter

与要替换的文档匹配的过滤器。
类型:Document

replacement

替换文档。
类型:Document

collation

(可选)对结果进行排序时使用的排序规则。要学习有关排序规则的更多信息,请参阅 排序规则部分的配置 CRUD 操作指南。
类型:StringObject

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 用于查询优化的索引 指南。
类型:Bson

此示例将执行以下动作:

  1. 在一个大量中指定三个 ClientBulkWriteModel 实例。前两个模型包含 movies集合中文档的替换指令,最后一个模型包含 users集合中文档的替换指令。

  2. 在客户端上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印已修改文档的数量。

const clientReplacements = [{
namespace: "sample_mflix.movies",
name: "replaceOne",
filter: {
title: "The Dark Knight"
},
replacement: {
title: "The Dark Knight Rises",
year: 2012,
rating: "PG-13"
}
}, {
namespace: "sample_mflix.movies",
name: "replaceOne",
filter: {
title: "Inception"
},
replacement: {
title: "Inception Reloaded",
year: 2010,
rating: "PG-13"
}
}, {
namespace: "sample_mflix.users",
name: "replaceOne",
filter: {
name: "April Cole"
},
replacement: {
name: "April Franklin",
email: "aprilfrank@example.com"
}
}];
const clientReplaceRes = await client.bulkWrite(clientReplacements);
console.log(`Modified documents: ${clientReplaceRes.modifiedCount}`);
Modified documents: 3

要执行批量更新操作,请为要进行的每个更新创建批量操作模型。然后,将这些模型的列表传递给 bulkWrite() 方法。

本节介绍如何执行以下类型的批量操作:

要对集合执行批量更新操作,请为每个操作创建一个 UpdateOneModelUpdateManyModel。然后,对集合调用 bulkWrite() 方法,并将模型大量作为参数传递。UpdateOneModel 仅更新与过滤匹配的一个文档,而 UpdateManyModel 会更新与过滤匹配的所有文档。

下表描述了您可以在 UpdateOneModelUpdateManyModel 中设立的字段:

字段
说明

filter

与要更新的一个或多个文档相匹配的过滤器。在 UpdateOneModel 中指定时,只更新第一个匹配的文档。在 UpdateManyModel 中指定时,所有匹配的文档都将更新。
类型:Document

update

要执行的更新。
类型:Document

arrayFilters

(可选)一设立过滤器,用于指定在更新数组值字段时要对哪些数组元素进行更新。
类型:Array

collation

(可选)对结果进行排序时使用的排序规则。要学习有关排序规则的更多信息,请参阅 排序规则部分的配置 CRUD 操作指南。
类型:Object

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 用于查询优化的索引 指南。
类型:String or Object

upsert

(可选)如果没有文档与过滤器匹配,是否创建新文档。默认下,此字段设立为 false
类型:Boolean

此示例将执行以下动作:

  1. 在大量中指定一个 UpdateOneModel 和一个 UpdateManyModel实例。 这些模型包含更新表示 movies集合中的电影的文档的指令。

  2. movies集合上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印已修改文档的数量。

const updateOperations = [{
updateOne: {
filter: {
title: "Interstellar"
},
update: {
$set: {
title: "Interstellar Updated",
genre: "Sci-Fi Adventure"
}
},
upsert: true
}
}, {
updateMany: {
filter: {
rated: "PG-13"
},
update: {
$set: {
rated: "PG-13 Updated",
genre: "Updated Genre"
}
}
}
}];
const updateResult = await movies.bulkWrite(updateOperations);
console.log(`Modified documents: ${updateResult.modifiedCount}`);
Modified documents: 2320

要跨多个集合或数据库执行批量更新操作,请为每个操作创建一个 ClientBulkWriteModel。然后,在客户端上调用 bulkWrite() 方法并将模型大量作为参数传递。

下表描述了您可以在 ClientBulkWriteModel 中设立以指定更新操作的字段:

字段
说明

namespace

要在其中更新文档的命名空间。
类型:String

name

要执行的操作。对于更新操作,请将此字段设立为 "updateOne""updateMany"
类型:String

filter

与要更新的一个或多个文档相匹配的过滤器。如果将模型 name设立为 "updateOne",则仅更新第一个匹配的文档。如果将 name 设立为 "updateMany",则所有匹配的文档都会更新。
类型:Document

update

要执行的更新。
类型:DocumentDocument[]

arrayFilters

(可选)一设立过滤器,用于指定在更新数组值字段时要对哪些数组元素进行更新。
类型:Document[]

collation

(可选)对结果进行排序时使用的排序规则。要学习有关排序规则的更多信息,请参阅 排序规则部分的配置 CRUD 操作指南。
类型:Document

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 用于查询优化的索引 指南。
类型:DocumentString

upsert

(可选)如果没有文档与过滤器匹配,是否创建新文档。默认下,此字段设立为 false
类型:Boolean

此示例将执行以下动作:

  1. 在大量中指定两个 ClientBulkWriteModel 实例。第一个模型指定对 movies集合进行多次更新操作,第二个模型指定对 users集合进行一次更新操作。

  2. 在客户端上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印已修改文档的数量。

const clientUpdates = [{
namespace: "sample_mflix.movies",
name: "updateMany",
filter: {
rated: "PG-13"
},
update: {
$set: {
rated: "PG-13 Updated",
genre: "Updated Genre"
}
},
upsert: false
}, {
namespace: "sample_mflix.users",
name: "updateOne",
filter: {
name: "Jon Snow"
},
update: {
$set: {
name: "Aegon Targaryen",
email: "targaryen@example.com"
}
},
upsert: false
}];
const clientUpdateRes = await client.bulkWrite(clientUpdates);
console.log(`Modified documents: ${clientUpdateRes.modifiedCount}`);
Modified documents: 2320

要执行批量删除操作,请为每个删除操作创建批量操作模型。然后,将这些模型的列表传递给 bulkWrite() 方法。

本节介绍如何执行以下类型的批量操作:

要对集合执行批量删除操作,请为每个操作创建一个 DeleteOneModelDeleteManyModel。然后,对集合调用 bulkWrite() 方法,并将模型大量作为参数传递。DeleteOneModel 仅删除与过滤匹配的一个文档,而 DeleteManyModel 会删除与过滤匹配的所有文档。

下表描述了可以在 DeleteOneModelDeleteManyModel 中设立的字段:

字段
说明

filter

与要删除的一个或多个文档相匹配的过滤器。在 DeleteOneModel 中指定时,仅删除第一个匹配的文档。在 DeleteManyModel 中指定时,将删除所有匹配的文档。
类型:Document

collation

(可选)对结果进行排序时使用的排序规则。要学习有关排序规则的更多信息,请参阅 排序规则部分的配置 CRUD 操作指南。
类型:Object

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 用于查询优化的索引 指南。
类型:String or Object

此示例将执行以下动作:

  1. 在大量中指定一个 DeleteOneModel 和一个 DeleteManyModel实例。这些模型包含删除movies集合中文档的指令。

  2. movies集合上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印已删除文档的数量。

const deleteOperations = [{
deleteOne: {
filter: {
title: "Dunkirk"
}
}
}, {
deleteMany: {
filter: {
rated: "R"
}
}
}];
const deleteResult = await movies.bulkWrite(deleteOperations);
console.log(`Deleted documents: ${deleteResult.deletedCount}`);
Deleted documents: 5538

要跨多个集合或数据库执行批量删除操作,请为每个操作创建一个 ClientBulkWriteModel。然后,在客户端上调用 bulkWrite() 方法并将模型大量作为参数传递。

下表描述了您可以在 ClientBulkWriteModel 中设立以指定删除操作的字段:

字段
说明

namespace

要在其中删除文档的命名空间空间。
类型:String

name

要执行的操作。对于删除操作,请将此字段设立为 "deleteOne""deleteMany"
类型:String

filter

与要删除的一个或多个文档相匹配的过滤器。如果将模型 name设立为 "deleteOne",则仅删除第一个匹配的文档。如果将 name 设立为 "deleteMany",则会删除所有匹配的文档。
类型:Document

hint

(可选)用于操作的索引。要学习;了解有关索引的更多信息,请参阅 用于查询优化的索引 指南。
类型:DocumentString

collation

(可选)对结果进行排序时使用的排序规则。要学习有关排序规则的更多信息,请参阅 排序规则部分的配置 CRUD 操作指南。
类型:Document

此示例将执行以下动作:

  1. 在大量中指定两个 ClientBulkWriteModel 实例。第一个模型指定对 movies集合执行“删除多个”操作,第二个模型指定对 users集合执行“删除一个”操作。

  2. 在客户端上调用 bulkWrite() 方法,并将模型大量作为参数传递。

  3. 打印已修改文档的数量。

const clientDeletes = [{
namespace: "sample_mflix.movies",
name: "deleteMany",
filter: {
rated: "R"
}
}, {
namespace: "sample_mflix.users",
name: "deleteOne",
filter: {
email: "emilia_clarke@gameofthron.es"
}
}];
const clientDeleteRes = await client.bulkWrite(clientDeletes);
console.log(`Deleted documents: ${clientDeleteRes.deletedCount}`);
Deleted documents: 5538

Collection.bulkWrite() 方法返回一个 BulkWriteResult对象,其中提供有关批量操作的信息。

下表描述了 BulkWriteResult对象的字段:

字段
说明

insertedCount

插入文档的数量

matchedCount

匹配文档的数量

modifiedCount

更新文档的数量

upsertedCount

已更新或插入的文档数量

deletedCount

已删除文档的数量

MongoClient.bulkWrite() 方法返回一个 ClientBulkWriteResult对象,其中包含有关客户端端批量写入操作的信息。

下表描述了 ClientBulkWriteResult对象的字段:

字段
说明

acknowledged

指示批量写入是否已确认的布尔值

insertedCount

插入文档的数量

matchedCount

匹配文档的数量

modifiedCount

更新文档的数量

upsertedCount

已更新或插入的文档数量

deletedCount

已删除文档的数量

insertResults

每个成功插入操作的结果

updateResults

每个成功更新操作的结果

deleteResults

每个成功删除操作的结果

如果对集合调用的任何批量写入操作不成功,则当 ordered 选项设立为 true 时,Node.js驱动程序会抛出 MongoBulkWriteError,并且不会执行任何进一步的操作。如果将 ordered设立false,则会尝试继续后续操作。

提示

要学习;了解有关有序和无序批量操作的更多信息,请参阅MongoDB Server手册中批量写入指南中的有序与无序操作部分。

MongoBulkWriteError对象包含以下属性:

属性
说明

message

错误消息。
类型:String

writeErrors

批量写入操作期间发生的错误的数组。
类型:BulkWriteError[]

writeConcernErrors

执行批量写入操作期间出现的写关注(write concern)错误。
类型:WriteConnectionError[]

result

在抛出异常之前成功执行的任何操作的结果。
类型:BulkWriteResult[]

err

根本的错误对象,其中可能包含更多详细信息。
类型:Error

如果在客户端上调用的任何批量写入操作不成功,Node.js驱动程序都会生成一个 MongoClientBulkWriteError。默认情况下,驱动程序在出现错误后不执行任何后续操作。如果将 ordered 选项传递给 bulkWrite() 方法并将其设立为 false,则驱动程序将继续尝试其余操作。

MongoClientBulkWriteError对象包含以下属性:

属性
说明

writeConcernErrors

指定每个写关注(write concern)错误的文档数组。
类型:Document[]

writeErrors

单个写入操作期间发生的错误的映射。
类型:Map<number, ClientBulkWriteError>

partialResult

客户端端批量写入的部分结果,反映了错误发生前的操作进度。
类型:ClientBulkWriteResult

注意

设置示例

This example connects to an instance of MongoDB by using a connection URI. To learn more about connecting to your MongoDB instance, see the Connect to MongoDB guide. This example also uses the movies collection in the sample_mflix database included in the Atlas sample datasets. You can load them into your database on the free tier of MongoDB Atlas by following the MongoDB Get Started.

以下代码是完整的独立运行文件,用于对 sample_mflix数据库中的 theaters集合执行批量写入操作。operations 参数包括 insertOneupdateManydeleteOne写入操作的示例:

1// Bulk write operation
2
3// Import MongoClient from the MongoDB node driver package
4const { MongoClient } = require("mongodb");
5
6// Replace the uri string with your MongoDB deployment's connection string
7const uri = "<connection string uri>";
8
9const client = new MongoClient(uri);
10
11async function run() {
12 try {
13 const database = client.db("sample_mflix");
14 const theaters = database.collection("theaters");
15
16 // Insert a new document into the "theaters" collection
17 const result = await theaters.bulkWrite([
18 {
19 insertOne: {
20 document: {
21 location: {
22 address: {
23 street1: "3 Main St.",
24 city: "Anchorage",
25 state: "AK",
26 zipcode: "99501",
27 },
28 },
29 },
30 },
31 },
32 {
33 insertOne: {
34 document: {
35 location: {
36 address: {
37 street1: "75 Penn Plaza",
38 city: "New York",
39 state: "NY",
40 zipcode: "10001",
41 },
42 },
43 },
44 },
45 },
46 {
47 // Update documents that match the specified filter
48 updateMany: {
49 filter: { "location.address.zipcode": "44011" },
50 update: { $set: { is_in_ohio: true } },
51 upsert: true,
52 },
53 },
54 {
55 // Delete a document that matches the specified filter
56 deleteOne: { filter: { "location.address.street1": "221b Baker St" } },
57 },
58 ]);
59 // Log the result of the bulk write operation
60 console.log(result);
61 } finally {
62 // Close the database connection when the operations are completed or if an error occurs
63 await client.close();
64 }
65}
66run().catch(console.dir);
1import { MongoClient } from "mongodb";
2
3// Replace the uri string with your MongoDB deployment's connection string.
4const uri = "<connection string uri>";
5
6const client = new MongoClient(uri);
7
8interface Address {
9 street1: string;
10 city: string;
11 state: string;
12 zipcode: string;
13}
14
15interface Theater {
16 location: { address: Address };
17 is_in_ohio?: boolean;
18}
19
20async function run() {
21 try {
22 const database = client.db("sample_mflix");
23 const theaters = database.collection<Theater>("theaters");
24
25 const result = await theaters.bulkWrite([
26 {
27 insertOne: {
28 document: {
29 location: {
30 address: {
31 street1: "3 Main St.",
32 city: "Anchorage",
33 state: "AK",
34 zipcode: "99501",
35 },
36 },
37 },
38 },
39 },
40 {
41 insertOne: {
42 document: {
43 location: {
44 address: {
45 street1: "75 Penn Plaza",
46 city: "New York",
47 state: "NY",
48 zipcode: "10001",
49 },
50 },
51 },
52 },
53 },
54 {
55 updateMany: {
56 // Important: You lose type safety when you use dot notation in queries
57 filter: { "location.address.zipcode": "44011" },
58 update: { $set: { is_in_ohio: true } },
59 upsert: true,
60 },
61 },
62 {
63 deleteOne: {
64 filter: { "location.address.street1": "221b Baker St" },
65 },
66 },
67 ]);
68
69 console.log(result);
70 } finally {
71 await client.close();
72 }
73}
74run().catch(console.dir);

运行上述示例将产生以下输出:

BulkWriteResult {
insertedCount: 2,
matchedCount: 1,
modifiedCount: 1,
deletedCount: 0,
upsertedCount: 0,
upsertedIds: {},
insertedIds: {
'0': new ObjectId("..."),
'1': new ObjectId("...")
}
}

要学习;了解有关批量操作的更多信息,请参阅MongoDB Server手册中的批量写入操作

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: