Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/ / /
Pymongo 驱动程序
/

批量写入操作

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

本指南中的示例使用 Atlas示例数据集中 sample_restaurants.restaurants集合。 要学习;了解如何创建免费的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 的实例。如果您使用类型检查工具,这将提供额外的类型安全性。您传递的实例必须从 TypedDict 类继承。

注意

Python 3.7 及更早版本中的 TypedDict

TypedDict 类位于typing 模块中,该模块仅在Python.3 8TypedDict及更高版本中可用。要在早期版本的Python中使用 类,请安装typing_extensions包。

以下示例使用自定义类构造一个 InsertOne实例,以提高类型安全性:

class Restaurant (TypedDict):
name: str
cuisine: str
borough: str
restaurant_id: str
operation = pymongo.InsertOne(Restaurant(
name="Mongo's Deli", cuisine="Sandwiches", borough="Manhattan", restaurant_id="1234"))

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

注意

_id字段必须是唯一的

在MongoDB集合中,每个文档都必须包含具有唯一值的 _id字段。

如果为 _id字段指定值,则必须确保该值在集合中是唯一的。如果不指定值,驾驶员会自动为该字段生成唯一的 ObjectId 值。

我们建议让驾驶员自动生成 _id 值以确保唯一性。重复的 _id 值违反了唯一索引约束,导致驾驶员返回错误。

要更新文档,请创建UpdateOne的实例并传入以下参数:

  • 查询筛选器,用于指定匹配集合中文档的条件

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

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 的实例。如果您使用类型检查工具,这将提供额外的类型安全性。您传递的实例必须从 TypedDict 类继承。

注意

Python 3.7 及更早版本中的 TypedDict

TypedDict 类位于typing 模块中,该模块仅在Python.3 8TypedDict及更高版本中可用。要在早期版本的Python中使用 类,请安装typing_extensions包。

以下示例使用自定义类构造了一个 ReplaceOne实例,以提高类型安全性:

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

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

提示

类型检查工具

要学习;了解有关Python可用的类型检查工具的更多信息,请参阅“工具”页面上的“类型检查器”。

要删除文档,请创建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 。 无论执行顺序如何,驾驶员在尝试所有操作后都会报告所有写关注(write concern)错误。

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

属性
说明

ordered

If True, the driver performs the write operations in the order provided. If an error occurs, the remaining operations are not attempted.

If False, the driver performs the operations in an arbitrary order and attempts to perform all operations.
Defaults to True.

bypass_document_validation

Specifies whether the operation bypasses document-level validation. For more information, see Schema Validation in the MongoDB Server manual.
Defaults to False.

session

An instance of ClientSession. For more information, see the API documentation.

comment

A comment to attach to the operation. For more information, see the delete command fields guide in the MongoDB Server manual.

let

A map of parameter names and values. 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.

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

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

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

注意

无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。

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

属性
说明

acknowledged

Indicates if the server acknowledged the write operation.

bulk_api_result

The raw bulk API result returned by the server.

deleted_count

The number of documents deleted, if any.

inserted_count

The number of documents inserted, if any.

matched_count

The number of documents matched for an update, if applicable.

modified_count

The number of documents modified, if any.

upserted_count

The number of documents upserted, if any.

upserted_ids

A map of the operation's index to the _id of the upserted documents, if applicable.

如果没有为 MongoClient对象添加类型注解,类型检查器可能会显示类似于以下内容的错误:

from pymongo import MongoClient
client = MongoClient() # error: Need type annotation for "client"

解决方案是将 MongoClient对象注释为 client: MongoClientclient: MongoClient[Dict[str, Any]]

如果您指定 MongoClient 作为类型提示,但不包含文档、键和值的数据类型,则类型检查器可能会显示类似于以下内容的错误:

error: Dict entry 0 has incompatible type "str": "int";
expected "Mapping[str, Any]": "int"

解决方案是将以下类型提示添加到 MongoClient对象:

client: MongoClient[Dict[str, Any]]

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

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档:

后退

Delete Documents

在此页面上