对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

批量写入操作

在本指南中,您可以学习;了解如何使用批量写入操作在单个数据库调用中执行多个写入操作。

考虑这样一种情况,您想将文档插入集合、更新多个其他文档,然后删除一个文档。如果您使用单个函数,则每个操作都需要进行一次数据库调用。相反,您可以利用批量操作来减少对数据库的调用次数。

C 驱动程序提供两个批量写入 API:mongoc_bulkwrite_t 和 mongoc_bulk_operation_t。

注意

如果您使用的是 MongoDB Server 8.0 或更高版本,我们建议您使用 mongoc_bulkwrite_t。它可以在一次调用中跨多个集合或数据库执行操作,而 mongoc_bulk_operation_t 每次调用只能针对一个集合。

The examples in this guide use the restaurants collection in the sample_restaurants database from 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.

批量写入操作包含一个或多个写入操作。要使用批量写入,创建批量写入类型,为要执行的每个操作调用相应的 append 函数,然后运行批量写入。

要创建批量写入操作,请调用 mongoc_client_bulkwrite_new() 函数。此函数返回类型为 mongoc_bulkwrite_t 的值,您可以使用该值来存储有关您要执行的写入操作的指令。将 mongoc_client_t 值作为参数传递,以指定批量写入的客户端。

mongoc_bulkwrite_t *bulk = mongoc_client_bulkwrite_new(client);

您可以将插入、更新、替换和删除操作追加到 mongoc_bulkwrite_t 值。

要执行插入操作,将插入指令添加到 mongoc_bulkwrite_t 值,这样就会将该操作作为批量写入的一部分进行排队。

以下示例调用 mongoc_bulkwrite_append_insertone() 函数。此函数接受以下参数:

Parameter
说明

self

要将操作添加到的 mongoc_bulkwrite_t 值。

ns

要插入文档的命名空间,指定为 <database>.<collection>。

document

要插入的文档。

opts

用于自定义操作的可选设置,或 NULL。

error

如果函数返回 false,则接收错误详情。

以下示例将一个插入操作添加到批量写入中:

bson_t *insert_doc = BCON_NEW( "name", BCON_UTF8("Mongo's Deli"), "cuisine", BCON_UTF8("Sandwiches"), "borough", BCON_UTF8("Manhattan"), "restaurant_id", BCON_UTF8("1234"));bson_error_t error; if (!mongoc_bulkwrite_append_insertone( bulk, "sample_restaurants.restaurants", insert_doc, NULL, &error)) { fprintf(stderr, "Failed to add insert operation: %s\n", error.message);} bson_destroy(insert_doc);

要插入多个文档,请对每个文档调用 mongoc_bulkwrite_append_insertone() 函数。

要执行更新操作,将更新说明添加到 mongoc_bulkwrite_t 值,这样就会将操作作为批量写入的一部分进行排队。

以下示例调用 mongoc_bulkwrite_append_updateone() 函数。此函数接受以下参数:

Parameter
说明

self

要将操作添加到的 mongoc_bulkwrite_t 值。

ns

包含要更新的文档的命名空间,指定为 <database>.<collection>。

filter

选择要更新的文档的查询筛选条件。

update

要应用于匹配文档的更新。

opts

用于自定义操作的可选设置,或 NULL。

error

如果函数返回 false,则接收错误详情。

以下示例将更新操作添加到批量写入中:

bson_t *filter_doc = BCON_NEW("name", BCON_UTF8("Mongo's Deli"));bson_t *update_doc = BCON_NEW("$set", "{", "cuisine", BCON_UTF8("Sandwiches and Salads"), "}");bson_error_t error; if (!mongoc_bulkwrite_append_updateone( bulk, "sample_restaurants.restaurants", filter_doc, update_doc, NULL, &error)) { fprintf(stderr, "Failed to add update operation: %s\n", error.message);} bson_destroy(filter_doc);bson_destroy(update_doc);

要更新多个文档,调用 mongoc_bulkwrite_append_updatemany() 函数并传递前面示例中显示的参数。这指示驱动程序更新与您的查询筛选条件匹配的 所有 文档。

以下示例将批量更新操作添加到批量写入操作中。

bson_t *filter_doc = BCON_NEW("name", BCON_UTF8("Mongo's Deli"));bson_t *update_doc = BCON_NEW("$set", "{", "cuisine", BCON_UTF8("Sandwiches and Salads"), "}");bson_error_t error; if (!mongoc_bulkwrite_append_updatemany( bulk, "sample_restaurants.restaurants", filter_doc, update_doc, NULL, &error)) { fprintf(stderr, "Failed to add update operation: %s\n", error.message);} bson_destroy(filter_doc);bson_destroy(update_doc);

替换操作删除指定文档中的所有字段和值,并将其替换为新的字段和值。要执行替换操作,将替换说明添加到 mongoc_bulkwrite_t 值,这样就会将该操作作为批量写入的一部分排入队列。

以下示例调用 mongoc_bulkwrite_append_replaceone() 函数。此函数接受以下参数:

Parameter
说明

self

要将操作添加到的 mongoc_bulkwrite_t 值。

ns

包含要替换的文档的命名空间,指定为 <database>.<collection>。

filter

选择要替换的文档的查询筛选条件。

replacement

替换匹配的文档的文档。

opts

用于自定义操作的可选设置,或 NULL。

error

如果函数返回 false,则接收错误详情。

以下示例将替换操作追加到批量写入中:

bson_t *filter_doc = BCON_NEW("restaurant_id", BCON_UTF8("1234"));bson_t *replace_doc = BCON_NEW( "name", BCON_UTF8("Mongo's Deli"), "cuisine", BCON_UTF8("Sandwiches and Salads"), "borough", BCON_UTF8("Brooklyn"), "restaurant_id", BCON_UTF8("5678"));bson_error_t error; if (!mongoc_bulkwrite_append_replaceone( bulk, "sample_restaurants.restaurants", filter_doc, replace_doc, NULL, &error)) { fprintf(stderr, "Failed to add replace operation: %s\n", error.message);} bson_destroy(filter_doc);bson_destroy(replace_doc);

要替换多个文档,请为每个文档调用 mongoc_bulkwrite_append_replaceone() 函数。

要执行删除操作,将删除指令添加到 mongoc_bulkwrite_t 值,这样就会将该操作作为批量写入的一部分进行排队。

以下示例调用 mongoc_bulkwrite_append_deleteone() 函数。此函数接受以下参数:

Parameter
说明

self

要将操作添加到的 mongoc_bulkwrite_t 值。

ns

包含要删除的文档的命名空间,指定为 <database>.<collection>。

filter

选择要删除的文档的查询筛选条件。

opts

用于自定义操作的可选设置,或 NULL。

error

如果函数返回 false,则接收错误详情。

以下示例将一个删除操作添加到批量写入。

bson_t *filter_doc = BCON_NEW("name", BCON_UTF8("Mongo's Deli"));bson_error_t error; if (!mongoc_bulkwrite_append_deleteone( bulk, "sample_restaurants.restaurants", filter_doc, NULL, &error)) { fprintf(stderr, "Failed to add delete operation: %s\n", error.message);} bson_destroy(filter_doc);

要删除多个文档,调用 mongoc_bulkwrite_append_deletemany() 函数并传递如前面的示例所示的参数。这指示驱动程序删除 所有 与您的查询筛选条件匹配的文档。

以下示例追加多次删除操作:

bson_t *filter_doc = BCON_NEW("borough", BCON_UTF8("Manhattan"));bson_error_t error; if (!mongoc_bulkwrite_append_deletemany( bulk, "sample_restaurants.restaurants", filter_doc, NULL, &error)) { fprintf(stderr, "Failed to add delete operation: %s\n", error.message);} bson_destroy(filter_doc);

mongoc_bulkwrite_execute() 函数接受以下参数:

Parameter
说明

self

mongoc_bulkwrite_t 值,包含每个写入操作的指令。

opts

用于自定义操作的可选设置,或 NULL。

如果操作成功,该函数将返回一个 mongoc_bulkwritereturn_t 值,其中包含操作结果。否则,返回值包含一个 mongoc_bulkwriteexception_t 值,并附带错误详情。

以下示例显示如何批量写入文档:

bson_error_t error; mongoc_bulkwrite_t *bulk = mongoc_client_bulkwrite_new(client); bson_t *insert_doc = BCON_NEW( "<field name 1>", BCON_UTF8("<value 1>"), "<field name 2>", BCON_UTF8("<value 2>"), "<field name 3>", BCON_UTF8("<value 3>"), "<field name 4>", BCON_UTF8("<value 4>")); mongoc_bulkwrite_append_insertone( bulk, "sample_restaurants.restaurants", insert_doc, NULL, &error);bson_destroy(insert_doc); bson_t *query = BCON_NEW("<field to match>", BCON_UTF8("<value to match>"));bson_t *update = BCON_NEW("$set", "{", "<field name>", BCON_UTF8("<value>"), "}"); mongoc_bulkwrite_append_updateone( bulk, "sample_restaurants.restaurants", query, update, NULL, &error);bson_destroy(query);bson_destroy(update); mongoc_bulkwritereturn_t result = mongoc_bulkwrite_execute(bulk, NULL); if (result.exc) { if (mongoc_bulkwriteexception_error(result.exc, &error)) { fprintf(stderr, "Bulk write error: %s\n", error.message); }} mongoc_bulkwriteresult_destroy(result.res);mongoc_bulkwriteexception_destroy(result.exc);mongoc_bulkwrite_destroy(bulk);

以下示例调用 mongoc_bulkwrite_execute() 函数执行 插入、更新、替换 和 删除 操作。

bson_error_t error;mongoc_bulkwritereturn_t result = mongoc_bulkwrite_execute(bulk, NULL); if (result.exc) { if (mongoc_bulkwriteexception_error(result.exc, &error)) { fprintf(stderr, "Bulk write error: %s\n", error.message); }} else if (result.res) { printf("Inserted: %" PRId64 " document(s)\n", mongoc_bulkwriteresult_insertedcount(result.res)); printf("Matched: %" PRId64 " document(s)\n", mongoc_bulkwriteresult_matchedcount(result.res)); printf("Modified: %" PRId64 " document(s)\n", mongoc_bulkwriteresult_modifiedcount(result.res)); printf("Deleted: %" PRId64 " document(s)\n", mongoc_bulkwriteresult_deletedcount(result.res));} mongoc_bulkwriteresult_destroy(result.res);mongoc_bulkwriteexception_destroy(result.exc);

如果任何写入操作失败,C 驱动程序将在返回值中报告错误,并不执行任何后续操作。

以下示例创建 mongoc_bulkwriteopts_t 值,将 ordered 设置为 false,并将选项传递给 mongoc_bulkwrite_execute():

mongoc_bulkwriteopts_t *opts = mongoc_bulkwriteopts_new();mongoc_bulkwriteopts_set_ordered(opts, false); mongoc_bulkwrite_t *bulk = mongoc_client_bulkwrite_new(client); // Perform bulk operation mongoc_bulkwritereturn_t result = mongoc_bulkwrite_execute(bulk, opts); mongoc_bulkwriteresult_destroy(result.res);mongoc_bulkwriteexception_destroy(result.exc); mongoc_bulkwriteopts_destroy(opts);mongoc_bulkwrite_destroy(bulk);

如果无序批量写入中的任何写入操作失败, C驱动程序仅在尝试所有操作后才会报告错误。

注意

无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。

下表描述了可以在 mongoc_bulkwriteopts_t 值中为批量写入操作指定的选项:

选项
说明

ordered

如果 true,则驱动程序会按照提供的顺序执行写入操作。如果发生错误,则不会尝试其他操作。

如果 false,则驱动程序会以任意顺序执行操作,并尝试执行所有操作。
默认为 true。

bypassdocumentvalidation

如果为 true,则允许写入操作选择退出文档级验证。

writeconcern

指定批量操作的写关注(write concern)。 有关更多信息,请参阅MongoDB Server手册中的写关注。

comment

为操作附加注释。 有关更多信息,请参阅MongoDB Server手册中的删除命令字段指南。

let

指定包含值列表的文档,以提高操作的可读性。 值必须是常量或不引用文档字段的闭合表达式。 有关更多信息,请参阅MongoDB Server手册中的 let声明。

verboseresults

如果 true,返回的结果包含每个成功操作的详细结果。

注意

当您使用的 C 驱动程序版本早于 1.28.0 时,请使用 mongoc_bulk_operation_t。针对早于 8.0 的 MongoDB Server 版本,或者只需要单集合写入。

批量写入操作包含一个或多个写入操作。要使用批量写入,创建批量写入类型,为要执行的每个操作调用相应的 append 函数,然后运行批量写入。

在运行批量写入操作之前,请调用 mongoc_collection_create_bulk_operation_with_opts() 函数。 此函数返回一个类型为 mongoc_bulk_operation_t 的值,您可以使用该值存储有关要执行哪些批量写入的指令。

mongoc_collection_create_bulk_operation_with_opts() 函数接受以下参数:

Parameter
说明

collection

要修改的collection。

opts

自定义操作的选项,或 NULL。

以下示例调用 mongoc_collection_create_bulk_operation_with_opts() 函数,并将 restaurants 集合作为参数传递:

mongoc_bulk_operation_t *bulk = mongoc_collection_create_bulk_operation_with_opts(collection, NULL);

您可以将插入、更新、替换和删除操作追加到 mongoc_bulk_operation_t 值。

要执行插入操作,将插入指令添加到 mongoc_bulk_operation_t 值,这样就会将该操作作为批量写入的一部分进行排队。

以下示例调用 mongoc_bulk_operation_insert_with_opts() 函数。此函数接受以下参数:

Parameter
说明

bulk

要将操作添加到的 mongoc_bulk_operation_t 值。

document

要插入的文档。

opts

用于自定义操作的可选设置,或 NULL。

error

用于 bson_error_t 错误值的可选位置。

以下示例将一个插入操作添加到批量写入中:

bson_t *insert_doc = BCON_NEW( "name", BCON_UTF8("Mongo's Deli"), "cuisine", BCON_UTF8("Sandwiches"), "borough", BCON_UTF8("Manhattan"), "restaurant_id", BCON_UTF8("1234"));bson_error_t error; if (!mongoc_bulk_operation_insert_with_opts(bulk, insert_doc, NULL, &error)) { fprintf(stderr, "Failed to add insert operation: %s\n", error.message);} bson_destroy(insert_doc);

要插入多个文档,请对每个文档调用 mongoc_bulk_operation_insert_with_opts() 函数。

要执行更新操作,将更新说明添加到 mongoc_bulk_operation_t 值,这样就会将操作作为批量写入的一部分进行排队。

以下示例调用 mongoc_bulk_operation_update_one_with_opts() 函数。此函数接受以下参数:

Parameter
说明

bulk

要将操作添加到的 mongoc_bulk_operation_t 值。

selector

选择要更新的文档的查询筛选条件。

document

要应用于匹配文档的更新。

opts

用于自定义操作的可选设置,或 NULL。

error

用于 bson_error_t 错误值的可选位置。

以下示例将更新操作添加到批量写入中:

bson_t *filter_doc = BCON_NEW("name", BCON_UTF8("Mongo's Deli"));bson_t *update_doc = BCON_NEW("$set", "{", "cuisine", BCON_UTF8("Sandwiches and Salads"), "}");bson_error_t error; if (!mongoc_bulk_operation_update_one_with_opts(bulk, filter_doc, update_doc, NULL, &error)) { fprintf(stderr, "Failed to add update operation: %s\n", error.message);} bson_destroy(filter_doc);bson_destroy(update_doc);

要更新多个文档,调用 mongoc_bulk_operation_update_many_with_opts() 函数,并传入前面示例中显示的参数。这指示驱动程序更新与您的查询筛选条件匹配的 所有 文档。

以下示例将批量更新操作添加到批量写入操作中。

bson_t *filter_doc = BCON_NEW("name", BCON_UTF8("Mongo's Deli"));bson_t *update_doc = BCON_NEW("$set", "{", "cuisine", BCON_UTF8("Sandwiches and Salads"), "}");bson_error_t error; if (!mongoc_bulk_operation_update_many_with_opts(bulk, filter_doc, update_doc, NULL, &error)) { fprintf(stderr, "Failed to add update operation: %s\n", error.message);} bson_destroy(filter_doc);bson_destroy(update_doc);

替换操作删除指定文档中的所有字段和值,并将其替换为新的字段和值。要执行替换操作,将替换说明添加到 mongoc_bulk_operation_t 值,这样就会将该操作作为批量写入的一部分排入队列。

以下示例调用 mongoc_bulk_operation_replace_one_with_opts() 函数。此函数接受以下参数:

Parameter
说明

bulk

要将操作添加到的 mongoc_bulk_operation_t 值。

selector

选择要替换的文档的查询筛选条件。

document

替换匹配的文档的文档。

opts

用于自定义操作的可选设置,或 NULL。

error

用于 bson_error_t 错误值的可选位置。

以下示例将替换操作追加到批量写入中:

bson_t *filter_doc = BCON_NEW("restaurant_id", BCON_UTF8("1234"));bson_t *replace_doc = BCON_NEW( "name", BCON_UTF8("Mongo's Deli"), "cuisine", BCON_UTF8("Sandwiches and Salads"), "borough", BCON_UTF8("Brooklyn"), "restaurant_id", BCON_UTF8("5678"));bson_error_t error; if (!mongoc_bulk_operation_replace_one_with_opts(bulk, filter_doc, replace_doc, NULL, &error)) { fprintf(stderr, "Failed to add replace operation: %s\n", error.message);} bson_destroy(filter_doc);bson_destroy(replace_doc);

要替换多个文档,请为每个文档调用 mongoc_bulk_operation_replace_one_with_opts() 函数。

要执行删除操作,将删除指令添加到 mongoc_bulk_operation_t 值,这样就会将该操作作为批量写入的一部分进行排队。

以下示例调用 mongoc_bulk_operation_remove_one_with_opts() 函数。此函数接受以下参数:

Parameter
说明

bulk

要将操作添加到的 mongoc_bulk_operation_t 值。

selector

选择要删除的文档的查询筛选条件。

opts

用于自定义操作的可选设置,或 NULL。

error

用于 bson_error_t 错误值的可选位置。

以下示例将一个删除操作添加到批量写入。

bson_t *filter_doc = BCON_NEW("restaurant_id", BCON_UTF8("5678"));bson_error_t error; if (!mongoc_bulk_operation_remove_one_with_opts(bulk, filter_doc, NULL, &error)) { fprintf(stderr, "Failed to add delete operation: %s\n", error.message);} bson_destroy(filter_doc);

要删除多个文档,调用 mongoc_bulk_operation_remove_many_with_opts() 函数并传入如前面示例所示的参数。这指示驱动程序删除 所有 与您的查询筛选条件匹配的文档。

以下示例将多文档删除操作添加到批量写入中。

bson_t *filter_doc = BCON_NEW("borough", BCON_UTF8("Manhattan"));bson_error_t error; if (!mongoc_bulk_operation_remove_many_with_opts(bulk, filter_doc, NULL, &error)) { fprintf(stderr, "Failed to add delete operation: %s\n", error.message);} bson_destroy(filter_doc);

mongoc_bulk_operation_execute() 函数接受以下参数:

Parameter
说明

bulk

mongoc_bulk_operation_t 值,包含每个写入操作的指令。

reply

指向用于结果文档的可覆盖存储的可选指针,或 NULL。

error

用于 bson_error_t 错误值的可选位置。

以下示例显示如何批量写入文档:

bson_error_t error; mongoc_bulk_operation_t *bulk = mongoc_collection_create_bulk_operation_with_opts(collection, NULL); bson_t *insert_doc = BCON_NEW( "<field name>", BCON_UTF8("<value>"), "<field name>", BCON_UTF8("<value>"), "<field name>", BCON_UTF8("<value>"), "<field name>", BCON_UTF8("<value>")); mongoc_bulk_operation_insert(bulk, insert_doc);bson_destroy(insert_doc); bson_t *query = BCON_NEW("<field to match>", BCON_UTF8("<value to match>"));bson_t *update = BCON_NEW("$set", "{", "<field name>", BCON_UTF8("<value>"), "}"); mongoc_bulk_operation_update_one(bulk, query, update, false);bson_destroy(query);bson_destroy(update); bool result = mongoc_bulk_operation_execute(bulk, NULL, &error);if (!result) { fprintf(stderr, "Bulk operation error: %s\n", error.message);} mongoc_bulk_operation_destroy(bulk);

以下示例调用 mongoc_bulk_operation_execute() 函数执行 插入、更新、替换 和 删除 操作。

bson_error_t error;bool result = mongoc_bulk_operation_execute(bulk, NULL, &error); if (!result) { printf("Bulk operation error: %s\n", error.message);} mongoc_bulk_operation_destroy(bulk);

如果任何写入操作失败,C 驱动程序将设置 error 输出参数,并不执行任何其他操作。

您可以通过传递一个指定选项值的 BSON 文档来修改 mongoc_collection_create_bulk_operation_with_opts() 函数的行为。

以下示例调用 mongoc_collection_create_bulk_operation_with_opts() 函数并将 ordered 选项设置为 false:

bson_t opts;BSON_APPEND_BOOL(&opts, "ordered", false);bulk = mongoc_collection_create_bulk_operation_with_opts(collection, &opts); // Perform bulk operation bson_destroy(&opts);mongoc_bulk_operation_destroy(bulk);

如果无序批量写入中的任何写入操作失败, C驱动程序仅在尝试所有操作后才会报告错误。

注意

无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。

以下表格描述了可以在传递给 mongoc_collection_create_bulk_operation_with_opts() 的选项文档中指定的选项:

选项
说明

ordered

如果 true,则驱动程序会按照提供的顺序执行写入操作。如果发生错误,则不会尝试其他操作。

如果 false,则驱动程序会以任意顺序执行操作,并尝试执行所有操作。
默认为 true。

writeConcern

指定批量操作的写关注(write concern)。 有关更多信息,请参阅MongoDB Server手册中的写关注。

sessionId

在指定的会话中运行批量操作。有关详细信息,请参阅 MongoDB Server 手册中的服务器会话。

comment

为操作附加注释。 有关更多信息,请参阅MongoDB Server手册中的删除命令字段指南。

let

指定包含值列表的文档,以提高操作的可读性。 值必须是常量或不引用文档字段的闭合表达式。 有关更多信息,请参阅MongoDB Server手册中的 let声明。

要了解如何执行单个写入操作,请参阅以下指南:

要学习;了解有关本指南中讨论的任何函数或类型的更多信息,请参阅以下API文档: