批量写入操作
概述
在本指南中,您可以了解如何使用 批量写入操作 在单个数据库调用中执行多个写入操作。
考虑一个场景,您想将一个文档插入到一个集合中,更新多个其他文档,然后删除一个文档。如果您使用单独的方法,每个操作都需要自己的数据库调用。相反,您可以使用批量操作来减少对数据库的调用次数。
示例数据
本指南中的示例使用来自sample_restaurants
数据库中的 restaurants
集合。要从您的 C++ 应用程序访问此集合,请实例化一个连接到 Atlas 集群的 mongocxx::client
,并将以下值分配给您的 db
和 collection
变量
auto db = client["sample_restaurants"]; auto collection = db["restaurants"];
要了解如何创建免费的 MongoDB Atlas 集群并加载示例数据集,请参阅 Atlas 入门 指南。
创建一个批量写入实例
在运行批量写入操作之前,对一个集合调用 create_bulk_write()
方法。此方法返回一个 mongocxx::bulk_write
类的实例,您可以用来存储有关要执行哪些类型批量写入的指令。
以下示例在 restaurants
集合上调用 create_bulk_write()
方法
auto bulk = collection.create_bulk_write();
然后,您可以向您的 mongocxx::bulk_write
实例追加写入模型来定义批量操作。有关更多信息,请参阅以下 定义写入操作 部分。
定义写入操作
对于您想要执行的所有写入操作,创建以下模型类之一的一个实例
mongocxx::model::insert_one
mongocxx::model::update_one
mongocxx::model::update_many
mongocxx::model::replace_one
mongocxx::model::delete_one
mongocxx::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 服务器手册中的字段更新运算符指南。
以下示例创建了一个 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
实例中设置的字段
字段 | 描述 |
---|---|
| 如果为 true ,则驱动程序按提供的顺序执行写入操作。如果发生错误,则不会尝试剩余的操作。如果为 false ,则驱动程序按任意顺序执行操作,并尝试执行所有操作。默认为 true 。 |
| 指定操作是否跳过文档级别的验证。有关更多信息,请参阅 MongoDB 服务器手册中的 模式验证。 默认为 false 。 |
| 指定批量操作的事务性。有关更多信息,请参阅MongoDB服务器手册中的事务性。 |
| 将注释附加到操作。有关更多信息,请参阅MongoDB服务器手册中的删除命令字段指南。 |
| 指定一个包含值列表的文档,以提高操作的可读性。值必须是常量或闭包表达式,不能引用文档字段。有关更多信息,请参阅MongoDB服务器手册中的let语句。 |
以下示例调用页面上的创建批量写入实例示例中的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
类的实例。该类包含以下成员函数
函数 | 描述 |
---|---|
| 如果有的话,返回删除的文档数量。 |
| 如果有的话,返回插入的文档数量。 |
| 如果适用,返回匹配更新的文档数量。 |
| 如果有的话,返回修改的文档数量。 |
| 如果有的话,返回更新的文档数量。 |
| 如果适用,返回一个映射,将操作的索引映射到插入文档的 _id 。 |
附加信息
要了解如何执行单个写操作,请参阅以下指南
API 文档
要了解更多关于本指南中讨论的任何方法或类型的信息,请参阅以下 API 文档