Overview
在本指南中,您可以学习如何使用 Ruby 驱动程序执行批量写入操作,从而在单个数据库调用中对数据进行多次更改。
考虑需要为同一任务插入文档、更新文档和删除文档的情况。如果使用单独写入方法,则每个写入操作将单独访问数据库。相反,您可以使用批量写入操作来优化应用程序对服务器的调用次数。
样本数据
本指南中的示例使用Atlas示例数据集的 sample_restaurants数据库中的 restaurants集合。要从Ruby应用程序访问权限此集合,请创建一个连接到Atlas 集群的Mongo::Client对象,并将以下值分配给 database 和 collection 变量:
database = client.use('sample_restaurants') collection = database[:restaurants]
要学习如何创建免费的MongoDB Atlas 集群并加载示例数据集,请参阅MongoDB 入门指南。
定义写入操作
对于要执行的每个写入操作,请创建一个哈希以实现以下操作之一:
insert_oneupdate_oneupdate_manyreplace_onedelete_onedelete_many
然后,将这些实例的列表传递给bulk_write方法。
以下部分介绍如何创建和使用上述操作的实例。执行批量操作部分演示了如何将哈希列表传递给 bulk_write 方法以执行批量操作。
插入操作
要执行插入操作,请创建一个 insert_one 哈希并指定要插入的文档。
以下示例创建了一个 insert_one 哈希:
insert_one = { insert_one: { name: 'Steve Rogers Cafe', borough: 'Brooklyn' } }
要插入多个文档,请为每个文档创建单独的 insert_one 哈希。
重要
执行批量操作时,insert_one 操作无法插入集合中已存在的具有 _id 的文档。在这种情况下,驱动程序会抛出 MongoBulkWriteException。
更新操作
要更新文档,请创建一个 update_one 哈希并传递以下参数:
查询过滤,指定用于匹配集合中文档的条件。
update_one 操作指定对与查询过滤匹配的第一个文档更新。
以下示例创建了一个 update_one 哈希:
update_one = { update_one: { filter: { name: 'Mountain View' }, update: { '$set': { borough: 'Queens' } } } }
要更新多个文档,请创建 update_many 哈希并传递与 update_one 操作相同的参数。update_many 操作指定对与查询过滤匹配的所有文档进行更新。
以下示例创建了一个 update_many 哈希:
update_many = { update_many: { filter: { name: 'Starbucks' }, update: { '$set': { cuisine: 'Cafe' } } } }
替换操作
替换操作会删除指定文档的所有字段和值,并将其替换为您指定的新字段和值。要执行替换操作,请创建一个 replace_one 哈希并传递以下参数:
查询过滤,指定用于匹配集合中文档的条件
指定要插入的新字段和值的替换文档
以下示例创建了一个 replace_one 哈希:
replace_one = { replace_one: { filter: { name: 'Old World Diner' }, replacement: { '$set': { name: 'New Age Luncheonette' } } } }
要替换多个文档,必须为每个文档创建一个 replace_one 哈希值。
删除操作
要删除文档,请创建 delete_one 哈希并传递查询过滤,指定要删除的文档。delete_one 操作仅删除与查询过滤匹配的第一个文档。
以下示例创建了一个 delete_one 哈希:
delete_one = { delete_one: { name: 'Old World Diner' } }
要删除多个文档,请创建 delete_many 哈希并传递查询过滤,指定要删除的文档。delete_many 操作会删除与查询过滤匹配的所有文档。
以下示例创建了一个 delete_many 哈希:
delete_many = { delete_many: { name: 'Starbucks' } }
执行批量操作
为要执行的每个操作定义哈希后,将这些对象的列表传递给 bulk_write 方法。默认下,该方法按照哈希列表指定的顺序运行操作。
以下示例使用bulk_write方法执行多个写入操作:
insert_one = { insert_one: { name: 'Nuovo Ristorante', borough: 'Brooklyn', cuisine: 'Italian' } } update_one = { update_one: { filter: { name: 'Moonlit Tavern' }, update: { '$set': { borough: 'Queens' } } } } delete_many = { delete_many: { name: 'Crepe' } } writes = [insert_one, update_one, delete_many] collection.bulk_write(writes)
如果任何写入操作失败, Ruby驱动程序都会引发 BulkWriteError,并且不会执行任何进一步的操作。BulkWriteError 提供了一个 details 项,其中包括失败的操作以及有关异常的详细信息。
注意
当驱动程序运行批量操作时,它会使用目标集合的写关注(write concern)。无论执行顺序如何,驱动程序在尝试所有操作后都会报告所有写关注(write concern)错误。
自定义批量写入操作
bulk_write 方法可以选择接受 options 哈希,该哈希指定可用于配置批量写入操作的选项。如果不指定任何选项,驱动程序将使用默认设置执行批量操作。
下表描述了可用于配置 bulk_write 方法的选项:
选项 | 说明 |
|---|---|
| 如果为 |
| |
| 用于操作的会话。类型: |
| 提供参数名称和值的映射,以便为操作设立顶级变量。值必须是常量或不引用文档字段的闭合表达式。 |
以下代码创建选项并将 ordered 选项设置为 false,以指定无序批量写入。然后,代码使用 bulk_write 方法执行与前面的示例相同的批量操作:
options = { ordered: false } collection.bulk_write(writes, options)
如果无序批量写入中的任何写入操作失败, Ruby驱动程序仅在尝试所有操作后才会报告错误。
注意
无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。
返回值
bulk_write 方法返回 BulkWrite::Result。您可以使用以下实例方法从 Result实例访问权限信息:
方法 | 说明 |
|---|---|
| 指示服务器是否确认了写入操作。 |
| 返回已删除的文档数量(如有)。 |
| 返回插入的文档数(如果有)。 |
| 返回已插入文档ID 的列表(如有)。 |
| 返回与更新匹配的文档数(如果适用)。 |
| 返回已修改的文档数(如有)。 |
| 返回已更新或插入的文档数量(如有)。 |
| 返回已更新或插入的文档ID 的列表(如果有)。 |
更多信息
要了解如何执行单个写入操作,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: