Overview
在本指南中,您可以学习;了解如何使用批量写入操作在单个数据库调用中执行多个写入操作。
考虑这样一种情况:您想要将一个文档插入到一个集合中,更新多个其他文档,然后删除一个文档。 如果使用单独的方法,则每个操作都需要调用自己的数据库。 相反,您可以使用批量操作来减少对数据库的调用次数。
样本数据
本指南中的示例使用Atlas示例数据集的sample_restaurants数据库中的restaurants集合。 要从C++应用程序访问权限此集合,请实例化一个连接到Atlas 集群的mongocxx::client ,并将以下值分配给db和collection变量:
auto db = client["sample_restaurants"]; auto collection = db["restaurants"];
要学习如何创建免费的MongoDB Atlas 集群并加载示例数据集,请参阅MongoDB 入门指南。
创建批量写入实例
在运行批量写入操作之前,请对集合调用create_bulk_write()方法。 此方法返回一个mongocxx::bulk_write类的实例,您可以使用该实例存储有关要执行哪些类型的批量写入的指令。
以下示例对restaurants集合调用create_bulk_write()方法:
auto bulk = collection.create_bulk_write();
然后,您可以将写入模型附加到mongocxx::bulk_write实例以定义批量操作。 有关更多信息,请参阅下面的“定义写入操作”部分。
定义写入操作
对于要执行的每个写入操作,请创建以下模型类之一的实例:
mongocxx::model::insert_onemongocxx::model::update_onemongocxx::model::update_manymongocxx::model::replace_onemongocxx::model::delete_onemongocxx::model::delete_many
然后,将每个写入模型附加到create_bulk_write()方法返回的mongocxx::bulk_write实例。
以下部分介绍如何创建和使用上述写入模型类的实例。
插入操作
要执行插入操作,请创建mongocxx::model::insert_one类的实例并指定要插入的文档。 然后,将模型实例附加到mongocxx::bulk_write类的实例。
以下示例创建了一个mongocxx::model::insert_one实例,并将其附加到名为bulk的mongocxx::bulk_write实例:
auto insert_doc = make_document(kvp("name", "Mongo's Deli"), kvp("cuisine", "Sandwiches"), kvp("borough", "Manhattan"), kvp("restaurant_id", "1234")); mongocxx::model::insert_one insert_op{insert_doc.view()}; bulk.append(insert_op);
要插入多个文档,请为每个文档创建一个mongocxx::model::insert_one实例。
更新操作
要更新文档,请创建 mongocxx::model::update_one 的实例。此模型指示驱动程序更新与查询筛选条件匹配的第一个文档。然后,将模型实例附加到 mongocxx::bulk_write 类的实例。
将以下参数传递给mongocxx::model::update_one模型:
查询过滤文档,指定用于匹配集合中的文档的条件。
更新文档,指定要执行的更新类型。 有关更新操作的更多信息,请参阅MongoDB Server手册中的字段更新操作符指南。
以下示例创建了一个mongocxx::model::update_one实例,并将其附加到名为bulk的mongocxx::bulk_write实例:
auto filter_doc = make_document(kvp("name", "Mongo's Deli")); auto update_doc = make_document(kvp("$set", make_document(kvp("cuisine", "Sandwiches and Salads")))); mongocxx::model::update_one update_op{filter_doc.view(), update_doc.view()}; bulk.append(update_op);
要更新多个文档,请创建 mongocxx::model::update_many 的实例并传入相同的参数。此模型指示驱动程序更新与查询筛选条件匹配的所有文档。
以下示例创建了一个mongocxx::model::update_many实例并将其附加到bulk :
auto filter_doc = make_document(kvp("name", "Mongo's Deli")); auto update_doc = make_document(kvp("$set", make_document(kvp("cuisine", "Sandwiches and Salads")))); mongocxx::model::update_many update_op{filter_doc.view(), update_doc.view()}; bulk.append(update_op);
替换操作
替换操作会删除指定文档的所有字段和值,然后替换为新的字段和值。 要执行替换操作,请创建mongocxx::model::replace_one类的实例,并向其传递查询过滤以及要在匹配文档中存储的字段和值。 然后,将模型实例附加到mongocxx::bulk_write类的实例。
以下示例创建了一个mongocxx::model::replace_one实例,并将其附加到名为bulk的mongocxx::bulk_write实例:
auto filter_doc = make_document(kvp("restaurant_id", "1234")); auto replace_doc = make_document(kvp("name", "Mongo's Deli"), kvp("cuisine", "Sandwiches and Salads"), kvp("borough", "Brooklyn"), kvp("restaurant_id", "5678")); mongocxx::model::replace_one replace_op{filter_doc.view(), replace_doc.view()}; bulk.append(replace_op);
要替换多个文档,必须为每个文档创建mongocxx::model::replace_one的新实例。
删除操作
要删除文档,请创建 mongocxx::model::delete_one 类的实例并传入查询筛选条件,指定要删除的文档。此模型指示驱动程序仅删除与查询筛选条件匹配的第一个文档。然后,将模型实例附加到 mongocxx::bulk_write 类的实例。
以下示例创建了一个mongocxx::model::delete_one实例,并将其附加到名为bulk的mongocxx::bulk_write实例:
auto filter_doc = make_document(kvp("restaurant_id", "5678")); mongocxx::model::delete_one delete_op{filter_doc.view()}; bulk.append(delete_op);
要删除多个文档,请创建 mongocxx::model::delete_many 类的实例并传入查询筛选条件,指定要删除的文档。此模型指示驱动程序删除与查询筛选条件匹配的所有文档。
以下示例创建了一个mongocxx::model::delete_many实例并将其附加到bulk :
auto filter_doc = make_document(kvp("borough", "Manhattan")); mongocxx::model::delete_many delete_op{filter_doc.view()}; bulk.append(delete_op);
运行批量操作
要运行批量操作,请对包含写入模型的mongocxx::bulk_write类的实例调用execute()方法。 默认, execute()方法按照操作附加到mongocxx::bulk_write实例的顺序运行这些操作。
以下示例通过将每个相应的写入模型附加到mongocxx::bulk_write的实例并调用execute()方法来执行本指南前面各部分中指定的插入、更新、替换和删除操作。 然后,它会打印已修改文档的数量:
auto bulk = collection.create_bulk_write(); // Specifies documents to insert, update, replace, or delete auto insert_doc = make_document(kvp("name", "Mongo's Deli"), kvp("cuisine", "Sandwiches"), kvp("borough", "Manhattan"), kvp("restaurant_id", "1234")); auto update_filter = make_document(kvp("name", "Mongo's Deli")); auto update_doc = make_document(kvp("$set", make_document(kvp("cuisine", "Sandwiches and Salads")))); auto replace_filter = make_document(kvp("restaurant_id", "1234")); auto replace_doc = make_document(kvp("name", "Mongo's Deli"), kvp("cuisine", "Sandwiches and Salads"), kvp("borough", "Brooklyn"), kvp("restaurant_id", "5678")); auto delete_filter = make_document(kvp("borough", "Manhattan")); // Creates write models for each write operation using the preceding documents mongocxx::model::insert_one insert_op{insert_doc.view()}; mongocxx::model::update_many update_op{update_filter.view(), update_doc.view()}; mongocxx::model::replace_one replace_op{replace_filter.view(), replace_doc.view()}; mongocxx::model::delete_many delete_op{delete_filter.view()}; // Appends each write model to the bulk operation bulk.append(insert_op); bulk.append(update_op); bulk.append(replace_op); bulk.append(delete_op); // Runs the bulk operation auto result = bulk.execute(); std::cout << "Modified documents: " << result->modified_count() << std::endl;
Modified documents: 2
如果任何写入操作失败, C++驱动程序将引发 mongocxx::bulk_write_exception 并且不会执行任何进一步的操作。
提示
要学习;了解有关modified_count()函数的详情,请参阅本指南的“返回值”部分。
自定义批量写入操作
您可以通过将mongocxx::options::bulk_write类的实例作为参数传递来修改create_bulk_write()方法的行为。 下表描述了您可以在mongocxx::options::bulk_write实例中设立的字段:
字段 | 说明 |
|---|---|
| 如果为 |
| |
| |
| |
|
以下示例调用本页创建批量写入实例示例中的create_bulk_write()方法,但将mongocxx::options::bulk_write实例的ordered字段设置为false :
mongocxx::options::bulk_write opts; opts.ordered(false); auto bulk = collection.create_bulk_write(opts);
如果无序批量写入中的任何写入操作失败, C++驱动程序仅在尝试所有操作后才会报告错误。
注意
无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。
返回值
execute()方法返回mongocxx::result::bulk_write类的实例。 mongocxx::result::bulk_write类包含以下成员函数:
function | 说明 |
|---|---|
| 返回已删除的文档数量(如有)。 |
| 返回插入的文档数(如果有)。 |
| 返回与更新匹配的文档数(如果适用)。 |
| 返回已修改的文档数(如有)。 |
| 返回已更新或插入的文档数(如有)。 |
| 返回操作索引到已更新或已插入文档的 |
更多信息
要了解如何执行单个写入操作,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: