文档菜单
文档首页
/ / /
PyMongo
/

批量写操作

本页内容

  • 概述
  • 示例数据
  • 定义写操作
  • 插入操作
  • 更新操作
  • 替换操作
  • 删除操作
  • 调用bulk_write() 方法
  • 自定义批量写操作
  • 返回值
  • 附加信息
  • API文档

考虑这样一个场景:你想要将一个文档插入到集合中,更新多个其他文档,然后删除一个文档。如果你使用单个方法,每个操作都需要自己的数据库调用。本指南将向您展示如何使用批量写操作在一次数据库调用中执行多个写操作。

本指南中的示例使用来自sample_restaurants.restaurants 集合的Atlas 示例数据集。要了解如何创建免费的 MongoDB Atlas 集群并加载示例数据集,请参阅使用 PyMongo 入门教程。

对于你想要执行的每个写操作,创建一个以下操作类之一的实例

  • InsertOne

  • UpdateOne

  • UpdateMany

  • ReplaceOne

  • DeleteOne

  • DeleteMany

然后,将这些实例的列表传递给 bulk_write() 方法。

以下各节将展示如何创建和使用这些类实例。

要执行插入操作,创建一个 InsertOne 实例,并指定您要插入的文档。

以下示例创建了一个 InsertOne 实例

operation = pymongo.InsertOne(
{
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Manhattan",
"restaurant_id": "1234"
}
)

要插入多个文档,为每个文档创建一个 InsertOne 实例。

注意

重复的 _id 值违反了唯一索引约束,导致驱动程序返回一个 DuplicateKeyError。为了避免此错误,请确保您插入的每个文档都有一个唯一的 _id 值。

要更新一个文档,创建一个 UpdateOne 实例,并传入以下参数

  • 一个 查询过滤器,用于指定匹配您集合中文档的条件

  • 您要执行的操作更新。有关更新操作的更多信息,请参阅 MongoDB 服务器手册中的 字段更新运算符指南。

UpdateOne 更新与您的查询过滤器匹配的第一个文档。

以下示例创建了一个 UpdateOne 实例

operation = pymongo.UpdateOne(
{ "name": "Mongo's Deli" },
{ "$set": { "cuisine": "Sandwiches and Salads" }},
)

要更新多个文档,创建一个 UpdateMany 实例,并传入相同的参数。UpdateMany 更新与您的查询过滤器匹配的所有文档。

以下示例创建了一个 UpdateMany 实例

operation = pymongo.UpdateMany(
{ "name": "Mongo's Deli" },
{ "$set": { "cuisine": "Sandwiches and Salads" }},
)

替换操作删除指定文档的所有字段和值,并用新的值替换它们。要执行替换操作,创建一个 ReplaceOne 实例,并传入一个查询过滤器以及您想要存储在匹配文档中的字段和值。

以下示例创建了一个 ReplaceOne 实例

operation = pymongo.ReplaceOne(
{ "restaurant_id": "1234" },
{
"name": "Mongo's Pizza",
"cuisine": "Pizza",
"borough": "Brooklyn",
"restaurant_id": "5678"
}
)

要替换多个文档,你必须为每个文档创建一个 ReplaceOne 实例。

要删除一个文档,创建一个 DeleteOne 实例,并传入一个查询过滤器,指定要删除的文档。 DeleteOne 只会移除与您的查询过滤器匹配的第一个文档。

以下示例创建了一个 DeleteOne 实例

operation = pymongo.DeleteOne({ "restaurant_id": "5678" })

要删除多个文档,创建一个 DeleteMany 实例,并传入一个查询过滤器,指定要删除的文档。 DeleteMany 会移除与您的查询过滤器匹配的所有文档。

以下示例创建了一个 DeleteMany 实例

operation = pymongo.DeleteMany({ "name": "Mongo's Deli" })

在定义了要执行的操作的每个类实例之后,将这些实例的列表传递给 bulk_write() 方法。默认情况下,该方法按照列表中定义的顺序执行操作。

以下示例使用 bulk_write() 方法执行多个写入操作

operations = [
pymongo.InsertOne(
{
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Manhattan",
"restaurant_id": "1234"
}
),
pymongo.InsertOne(
{
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Brooklyn",
"restaurant_id": "5678"
}
),
pymongo.UpdateMany(
{ "name": "Mongo's Deli" },
{ "$set": { "cuisine": "Sandwiches and Salads" }},
),
pymongo.DeleteOne(
{ "restaurant_id": "1234" }
)
]
results = restaurants.bulk_write(operations)
print(results)
BulkWriteResult({'writeErrors': [], 'writeConcernErrors': [], 'nInserted': 2, 'nUpserted': 0, 'nMatched': 2, 'nModified': 2, 'nRemoved': 1, 'upserted': []}, acknowledged=True)

如果任何写入操作失败,PyMongo 将引发一个 BulkWriteError,并且不会执行任何进一步的操作。 BulkWriteError 提供一个 details 属性,其中包含失败的操作以及异常的详细信息。

注意

当 PyMongo 执行批量操作时,它使用正在运行操作集合的 write_concern。驱动程序在尝试所有操作后报告所有写入关心错误,无论执行顺序如何。

bulk_write() 方法可以接受额外的参数,这些参数表示可以用来配置批量写入操作的选项。如果您没有指定任何额外的选项,驱动程序不会自定义批量写入操作。

属性
描述
ordered
如果设置为 True,驱动程序将按照提供的顺序执行写入操作。如果发生错误,将不会尝试剩余的操作。

如果设置为 False,驱动程序将按照任意顺序执行操作并尝试执行所有操作。
默认为 True
bypass_document_validation
指定操作是否跳过文档级别的验证。有关更多信息,请参阅 MongoDB 服务器手册中的 模式验证
默认为 False
session
ClientSession 的实例。有关更多信息,请参阅 API 文档
comment
要附加到操作的注释。有关更多信息,请参阅 MongoDB 服务器手册中的 删除命令字段 指南。
let
参数名称和值的映射。值必须是常量或封闭表达式,不能引用文档字段。有关更多信息,请参阅 MongoDB 服务器手册中的 let 语句

以下示例调用了上一个示例中的bulk_write()方法,并将ordered选项设置为False

results = restaurants.bulk_write(operations, ordered=False)

如果无序批量写入中的任何写操作失败,PyMongo仅在尝试所有操作后报告错误。

注意

无序批量操作不保证执行顺序。顺序可能与你列出的顺序不同,以优化运行时间。

bulk_write()方法返回一个BulkWriteResult对象。该BulkWriteResult对象包含以下属性

属性
描述
acknowledged
指示服务器是否确认了写操作。
bulk_api_result
服务器返回的原始批量API结果。
deleted_count
如果有的话,删除的文档数量。
inserted_count
如果有的话,插入的文档数量。
matched_count
如果适用,匹配更新操作的文档数量。
modified_count
如果有的话,修改的文档数量。
upserted_count
如果有的话,更新插入的文档数量。
upserted_ids
如果适用,操作索引到更新插入文档的_id的映射。

要了解如何执行单个写操作,请参阅以下指南

要了解更多关于本指南中讨论的任何方法或类型,请参阅以下API文档

返回

删除