Overview
In this guide, you can learn how to perform multiple write operations in a single database call by using bulk write operations.
Consider a scenario in which you want to insert a document into a collection, update multiple other documents, and then delete a document. If you use individual functions, each operation requires its own database call. Instead, you can use a bulk operation to reduce the number of calls to the database.
The C driver provides two bulk write APIs: mongoc_bulkwrite_t and mongoc_bulk_operation_t.
Note
If you're using MongoDB Server 8.0 or later, we recommend that you use mongoc_bulkwrite_t. It can perform operations across multiple collections or databases in one call, while mongoc_bulk_operation_t can target only one collection per call.
Sample Data
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
Bulk write operations contain one or more write operations. To use a bulk write, create the bulk write type, call the corresponding append function for each operation that you want to perform, and then run the bulk write.
Create the Bulk Write Operation
To create a bulk write operation, call the mongoc_client_bulkwrite_new() function. This function returns a value of type mongoc_bulkwrite_t that you can use to store instructions about which write operations you want to perform. Pass a mongoc_client_t value as a parameter to specify the client for the bulk write.
mongoc_bulkwrite_t *bulk = mongoc_client_bulkwrite_new(client);
Append to the Bulk Write Operation
You can append insert, update, replace, and delete operations to your mongoc_bulkwrite_t value.
Insert Operations
To perform an insert operation, add the insert instructions to the mongoc_bulkwrite_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulkwrite_append_insertone() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The namespace to insert the document into, specified as |
| The document to insert. |
| Optional settings to customize the operation, or |
| Receives error details if the function returns |
The following example appends an insert operation to the bulk write:
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);
To insert multiple documents, call the mongoc_bulkwrite_append_insertone() function for each document.
Update Operations
To perform an update operation, add the update instructions to the mongoc_bulkwrite_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulkwrite_append_updateone() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The namespace containing the documents to update, specified as |
| The query filter that selects the document to update. |
| The update to apply to the matched document. |
| Optional settings to customize the operation, or |
| Receives error details if the function returns |
The following example appends an update operation to the bulk write:
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);
To update multiple documents, call the mongoc_bulkwrite_append_updatemany() function and pass the parameters shown in the preceding example. This instructs the driver to update all documents that match your query filter.
The following example appends an update many operation to the bulk write:
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);
Replace Operations
A replace operation removes all fields and values of a specified document and replaces them with new ones. To perform a replace operation, add the replacement instructions to the mongoc_bulkwrite_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulkwrite_append_replaceone() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The namespace containing the documents to replace, specified as |
| The query filter that selects the document to replace. |
| The document that replaces the matched document. |
| Optional settings to customize the operation, or |
| Receives error details if the function returns |
The following example appends a replace operation to the bulk write:
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);
To replace multiple documents, call the mongoc_bulkwrite_append_replaceone() function for each document.
Delete Operations
To perform a delete operation, add the delete instructions to the mongoc_bulkwrite_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulkwrite_append_deleteone() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The namespace containing the documents to delete, specified as |
| The query filter that selects the document to delete. |
| Optional settings to customize the operation, or |
| Receives error details if the function returns |
The following example appends a delete operation to the bulk write:
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);
To delete multiple documents, call the mongoc_bulkwrite_append_deletemany() function and pass the parameters shown in the preceding example. This instructs the driver to delete all documents that match your query filter.
The following example appends a delete many operation:
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);
Run the Bulk Operation
The mongoc_bulkwrite_execute() function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| Optional settings to customize the operation, or |
If the operation is successful, the function returns a mongoc_bulkwritereturn_t value that contains the operation results. Otherwise, the return value includes a mongoc_bulkwriteexception_t value with the error details.
The following example shows how to bulk write documents:
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);
The following example calls the mongoc_bulkwrite_execute() function to perform the insert, update, replace, and delete operations.
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);
If any write operations fail, the C driver reports the errors in the return value and does not perform any further operations.
Customize Bulk Write Operations
The following example creates a mongoc_bulkwriteopts_t value, sets ordered to false, and passes the options to 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);
If any of the write operations in an unordered bulk write fail, the C driver reports the errors only after attempting all operations.
Note
Unordered bulk operations do not guarantee order of execution. The order can differ from the way you list them to optimize the runtime.
Bulk Write Options
The following table describes the options you can specify in the mongoc_bulkwriteopts_t value for a bulk write operation:
Option | Description |
|---|---|
| If |
| If |
| Specifies the write concern for the bulk operation. For more information, see Write Concern in the MongoDB Server manual. |
| Attaches a comment to the operation. For more information, see the delete command fields guide in the MongoDB Server manual. |
| Specifies a document with a list of values to improve operation readability. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual. |
| If |
mongoc_bulk_operation_t
Note
Use mongoc_bulk_operation_t when you're using an earlier C driver version than 1.28.0, targeting a MongoDB Server version older than 8.0, or only need single-collection writes.
Bulk write operations contain one or more write operations. To use a bulk write, create the bulk write type, call the corresponding append function for each operation that you want to perform, and then run the bulk write.
Create the Bulk Write Operation
Before running a bulk write operation, call the mongoc_collection_create_bulk_operation_with_opts() function. This function returns a value of type mongoc_bulk_operation_t that you can use to store instructions about which bulk writes to perform.
The mongoc_collection_create_bulk_operation_with_opts() function accepts the following parameters:
Parameter | Description |
|---|---|
| The collection to modify. |
| Options to customize the operation, or |
The following example calls the mongoc_collection_create_bulk_operation_with_opts() function, passing the restaurants collection as a parameter:
mongoc_bulk_operation_t *bulk = mongoc_collection_create_bulk_operation_with_opts(collection, NULL);
Append to the Bulk Write Operation
You can append insert, update, replace, and delete operations to your mongoc_bulk_operation_t value.
Insert Operations
To perform an insert operation, add the insert instructions to the mongoc_bulk_operation_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulk_operation_insert_with_opts() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The document to insert. |
| Optional settings to customize the operation, or |
| An optional location for a |
The following example appends an insert operation to the bulk write:
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);
To insert multiple documents, call the mongoc_bulk_operation_insert_with_opts() function for each document.
Update Operations
To perform an update operation, add the update instructions to the mongoc_bulk_operation_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulk_operation_update_one_with_opts() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The query filter that selects the document to update. |
| The update to apply to the matched document. |
| Optional settings to customize the operation, or |
| An optional location for a |
The following example appends an update operation to the bulk write:
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);
To update multiple documents, call the mongoc_bulk_operation_update_many_with_opts() function and pass in the parameters shown in the preceding example. This instructs the driver to update all documents that match your query filter.
The following example appends an update many operation to the bulk write:
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);
Replace Operations
A replace operation removes all fields and values of a specified document and replaces them with new ones. To perform a replace operation, add the replacement instructions to the mongoc_bulk_operation_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulk_operation_replace_one_with_opts() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The query filter that selects the document to replace. |
| The document that replaces the matched document. |
| Optional settings to customize the operation, or |
| An optional location for a |
The following example appends a replace operation to the bulk write:
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);
To replace multiple documents, call the mongoc_bulk_operation_replace_one_with_opts() function for each document.
Delete Operations
To perform a delete operation, add the delete instructions to the mongoc_bulk_operation_t value, which queues the operation as part of the bulk write.
The following example calls the mongoc_bulk_operation_remove_one_with_opts() function. This function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| The query filter that selects the document to delete. |
| Optional settings to customize the operation, or |
| An optional location for a |
The following example appends a delete operation to the bulk write:
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);
To delete multiple documents, call the mongoc_bulk_operation_remove_many_with_opts() function and pass in the parameters shown in the preceding example. This instructs the driver to delete all documents that match your query filter.
The following example appends a delete many operation to the bulk write:
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);
Run the Bulk Operation
The mongoc_bulk_operation_execute() function accepts the following parameters:
Parameter | Description |
|---|---|
| The |
| An optional pointer to overwritable storage for the results document, or |
| An optional location for a |
The following example shows how to bulk write documents:
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);
The following example calls the mongoc_bulk_operation_execute() function to perform the insert, update, replace, and delete operations.
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);
If any write operations fail, the C driver sets the error output parameter and does not perform any further operations.
Customize Bulk Write Operations
You can modify the behavior of the mongoc_collection_create_bulk_operation_with_opts() function by passing a BSON document that specifies option values.
The following example calls the mongoc_collection_create_bulk_operation_with_opts() function and sets the ordered option to 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);
If any of the write operations in an unordered bulk write fail, the C driver reports the errors only after attempting all operations.
Note
Unordered bulk operations do not guarantee order of execution. The order can differ from the way you list them to optimize the runtime.
Bulk Write Options
The following table describes the options you can specify in the options document you pass to mongoc_collection_create_bulk_operation_with_opts():
Option | Description |
|---|---|
| If |
| Specifies the write concern for the bulk operation. For more information, see Write Concern in the MongoDB Server manual. |
| Runs the bulk operations within the specified session. For more information, see Server Sessions in the MongoDB Server manual. |
| Attaches a comment to the operation. For more information, see the delete command fields guide in the MongoDB Server manual. |
| Specifies a document with a list of values to improve operation readability. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual. |
Additional Information
To learn how to perform individual write operations, see the following guides:
API Documentation
To learn more about any of the functions or types discussed in this guide, see the following API documentation:
- mongoc_bulkwrite_t
- mongoc_bulk_operation_t