Overview
在本指南中,您可以学习;了解如何使用批量写入操作在单个数据库调用中执行多个写入操作。
考虑这样一种情况,您想将文档插入集合、更新多个其他文档,然后删除一个文档。如果您使用单个函数,则每个操作都需要进行一次数据库调用。相反,您可以利用批量操作来减少对数据库的调用次数。
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.
mongoc_bulkwrite_t
批量写入操作包含一个或多个写入操作。要使用批量写入,创建批量写入类型,为要执行的每个操作调用相应的 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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 要插入文档的命名空间,指定为 |
| 要插入的文档。 |
| 用于自定义操作的可选设置,或 |
| 如果函数返回 |
以下示例将一个插入操作添加到批量写入中:
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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 包含要更新的文档的命名空间,指定为 |
| 选择要更新的文档的查询筛选条件。 |
| 要应用于匹配文档的更新。 |
| 用于自定义操作的可选设置,或 |
| 如果函数返回 |
以下示例将更新操作添加到批量写入中:
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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 包含要替换的文档的命名空间,指定为 |
| 选择要替换的文档的查询筛选条件。 |
| 替换匹配的文档的文档。 |
| 用于自定义操作的可选设置,或 |
| 如果函数返回 |
以下示例将替换操作追加到批量写入中:
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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 包含要删除的文档的命名空间,指定为 |
| 选择要删除的文档的查询筛选条件。 |
| 用于自定义操作的可选设置,或 |
| 如果函数返回 |
以下示例将一个删除操作添加到批量写入。
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 | 说明 |
|---|---|
|
|
| 用于自定义操作的可选设置,或 |
如果操作成功,该函数将返回一个 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驱动程序仅在尝试所有操作后才会报告错误。
注意
无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。
BulkWriteOptions
下表描述了可以在 mongoc_bulkwriteopts_t 值中为批量写入操作指定的选项:
选项 | 说明 |
|---|---|
| 如果 |
| 如果为 |
| |
| |
| |
| 如果 |
mongoc_bulk_operation_t
注意
当您使用的 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。 |
| 自定义操作的选项,或 |
以下示例调用 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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 要插入的文档。 |
| 用于自定义操作的可选设置,或 |
| 用于 |
以下示例将一个插入操作添加到批量写入中:
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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 选择要更新的文档的查询筛选条件。 |
| 要应用于匹配文档的更新。 |
| 用于自定义操作的可选设置,或 |
| 用于 |
以下示例将更新操作添加到批量写入中:
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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 选择要替换的文档的查询筛选条件。 |
| 替换匹配的文档的文档。 |
| 用于自定义操作的可选设置,或 |
| 用于 |
以下示例将替换操作追加到批量写入中:
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 | 说明 |
|---|---|
| 要将操作添加到的 |
| 选择要删除的文档的查询筛选条件。 |
| 用于自定义操作的可选设置,或 |
| 用于 |
以下示例将一个删除操作添加到批量写入。
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 | 说明 |
|---|---|
|
|
| 指向用于结果文档的可覆盖存储的可选指针,或 |
| 用于 |
以下示例显示如何批量写入文档:
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驱动程序仅在尝试所有操作后才会报告错误。
注意
无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。
BulkWriteOptions
以下表格描述了可以在传递给 mongoc_collection_create_bulk_operation_with_opts() 的选项文档中指定的选项:
选项 | 说明 |
|---|---|
| 如果 |
| |
| 在指定的会话中运行批量操作。有关详细信息,请参阅 MongoDB Server 手册中的服务器会话。 |
| |
|
更多信息
要了解如何执行单个写入操作,请参阅以下指南:
API 文档
要学习;了解有关本指南中讨论的任何函数或类型的更多信息,请参阅以下API文档:
- mongoc_bulkwrite_t
- mongoc_bulk_operation_t