Docs Menu

一括書き込み操作

このガイドでは、 PyMongoを使用して一括操作を実行する方法を学習できます。一括操作では、単一のメソッドで複数の書込み (write) 操作を実行することで、サーバーへの呼び出し回数を減らします。

Collection クラスと MongoClient クラスはどちらも bulk_write() メソッドを提供します。Collectionインスタンスで bulk_write() を呼び出すと、1 つのコレクションに対して複数の書き込み操作を実行できます。MongoClientインスタンスで bulk_write() を呼び出すと、複数の名前空間にわたって一括書込みを実行できます。MongoDBでは、名前空間はデータベース名とコレクション名で形式<database>.<collection> で構成されています。

重要

MongoClientインスタンスで一括操作を実行するには、アプリケーションが次の要件を満たしていることを確認します。

  • PyMongo v4.9 以降を使用

  • MongoDB Server v8.0 以降に接続

このガイドの例では、Atlasサンプルデータセットsample_restaurants.restaurants コレクションと sample_mflix.movies コレクションを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 「 PyMongoを使い始める 」チュートリアルを参照してください。

実行する書込み操作ごとに、次のいずれかの操作クラスのインスタンスを作成します。

  • InsertOne

  • UpdateOne

  • UpdateMany

  • ReplaceOne

  • DeleteOne

  • DeleteMany

次に、これらのインスタンスのリストをbulk_write()メソッドに渡します。

重要

次のコードに示すように、書込み (write)操作クラスをアプリケーションファイルに必ずインポートしてください。

from pymongo import InsertOne, UpdateOne, UpdateMany, ReplaceOne, DeleteOne, DeleteMany

次のセクションでは、コレクションおよびクライアントの一括操作を実行するために使用できる前述のクラスのインスタンスを作成する方法を示します。

挿入操作を実行するには、InsertOne のインスタンスを作成し、挿入するドキュメントを指定します。次のキーワード引数を InsertOne コンストラクターに渡します。

  • namespace:ドキュメントを挿入する名前空間空間。この引数は、単一のコレクションに対して 一括操作 を実行する場合は任意です。

  • document: 挿入するドキュメント。

次の例では、 InsertOneのインスタンスを作成しています。

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

カスタムクラスのインスタンスをコンストラクターに渡すことで、InsertOne のインスタンスを作成することもできます。これにより、型チェックツールを使用している場合、追加の型の安全性が確保されます。渡すインスタンスは、TypedDictクラスから継承する必要があります。

注意

Python 3.7 以前の TypedDiction

TypedDictionクラスは typing モジュールにあります。このモジュールはPython 3.8 以降でのみ利用可能です。Pythonの以前のバージョンで TypedDictクラスを使用するには、 mapping_extentionsパッケージをインストールします。

次の例では、型の安全性を高めるためにカスタムクラスを使用して 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のインスタンスを作成し、次の引数を渡します。

  • namespace: 更新を実行する名前空間空間。この引数は、単一のコレクションに対して 一括操作 を実行する場合は任意です。

  • filter:コレクション内のドキュメントをマッチングするために使用される基準を指定するクエリフィルター。

  • update: 実行する更新。更新操作の詳細については、 MongoDB Serverマニュアルの「 フィールド更新演算子 」ガイドを参照してください。

UpdateOneは、クエリフィルターに一致する最初のドキュメントを更新します。

次の例では、 UpdateOneのインスタンスを作成しています。

operation = UpdateOne(
namespace="sample_restaurants.restaurants",
filter={ "name": "Mongo's Deli" },
update={ "$set": { "cuisine": "Sandwiches and Salads" }}
)

複数のドキュメントを更新するには、 UpdateManyのインスタンスを作成し、同じ引数で渡します。 UpdateManyは、クエリフィルターに一致するすべてのドキュメントを更新します。

次の例では、 UpdateManyのインスタンスを作成しています。

operation = UpdateMany(
namespace="sample_restaurants.restaurants",
filter={ "name": "Mongo's Deli" },
update={ "$set": { "cuisine": "Sandwiches and Salads" }}
)

置換操作、指定されたドキュメントのすべてのフィールドと値が削除され、新しいフィールドと値に置き換えられます。置換操作を実行するには、ReplaceOne のインスタンスを作成し、次の引数を渡します。

  • namespace: 置換操作を実行する名前空間空間。この引数は、単一のコレクションに対して 一括操作 を実行する場合は任意です。

  • filter: 置き換えるドキュメントを一致させるために使用される条件を指定するクエリフィルター

  • replacement: 一致するドキュメントに保存する新しいフィールドと値を含むドキュメント。

次の例では、 ReplaceOneのインスタンスを作成しています。

operation = ReplaceOne(
namespace="sample_restaurants.restaurants",
filter={ "restaurant_id": "1234" },
replacement={
"name": "Mongo's Pizza",
"cuisine": "Pizza",
"borough": "Brooklyn",
"restaurant_id": "5678"
}
)

カスタムクラスのインスタンスをコンストラクターに渡すことで、ReplaceOne のインスタンスを作成することもできます。これにより、型チェックツールを使用している場合、追加の型の安全性が確保されます。渡すインスタンスは、TypedDictクラスから継承する必要があります。

注意

Python 3.7 以前の TypedDiction

TypedDictionクラスは typing モジュールにあります。このモジュールはPython 3.8 以降でのみ利用可能です。Pythonの以前のバージョンで TypedDictクラスを使用するには、 mapping_extentionsパッケージをインストールします。

次の例では、型の安全性を高めるためにカスタムクラスを使用して 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のインスタンスを作成する必要があります。

Tip

タイプチェックツール

Pythonで利用可能な型チェックツールの詳細については、 ツール ページの「型チェッカー」を参照してください。

ドキュメントを削除するには、DeleteOne のインスタンスを作成し、次の引数を渡します。

  • namespace:ドキュメントを削除する名前空間空間。この引数は、単一のコレクションに対して 一括操作 を実行する場合は任意です。

  • filter: 削除するドキュメントをマッチングするために使用される基準を指定するクエリフィルター。

DeleteOne はクエリフィルターに一致する最初のドキュメントのみを削除します。

次の例では、 DeleteOneのインスタンスを作成しています。

operation = DeleteOne(
namespace="sample_restaurants.restaurants",
filter={ "restaurant_id": "5678" }
)

複数のドキュメントを削除するには、DeleteMany のインスタンスを作成し、削除するドキュメントを指定する名前空間とクエリフィルターを渡します。DeleteMany は、クエリフィルターに一致するすべてのドキュメントを削除します。

次の例では、 DeleteManyのインスタンスを作成しています。

operation = DeleteMany(
namespace="sample_restaurants.restaurants",
filter={ "name": "Mongo's Deli" }
)

実行する操作ごとにクラスインスタンスを定義したら、これらのインスタンスのリストを bulk_write() メソッドに渡します。単一のコレクションに書込むには Collectionインスタンスで bulk_write() メソッドを呼び出し、複数の名前空間に書込むには MongoClientインスタンスの メソッドを呼び出します。

Collection で呼び出された書込み操作のいずれかが失敗した場合、 PyMongo はBulkWriteError を発生させ、それ以上の操作を実行しません。BulkWriteError は、失敗した操作を含む details 属性と例外に関する詳細を提供します。

MongoClient で呼び出された書込み操作のいずれかが失敗した場合、 PyMongo はClientBulkWriteException を発生させ、それ以上の操作を実行しません。ClientBulkWriteException は、例外に関する情報を含む error 属性を提供します。

注意

PyMongo が一括操作を実行する場合、操作が実行中いるコレクションまたはクライアントの write_concern が使用されます。MongoClient.bulk_write() メソッドを使用して、操作に書込み保証 (write concern)を設定することもできます。ドライバーは、実行順序に関係なく、すべての操作を試行した後にすべての書込み保証 (write concern)エラーを報告します。

書込み保証 (write concern) の詳細については、 MongoDB Serverマニュアルの「 書込み保証 (write concern) 」を参照してください。

次の例では、Collectionインスタンスで bulk_write() メソッドを使用して、restaurantsコレクションに対して複数の書込み操作を実行します。

operations = [
InsertOne(
document={
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Manhattan",
"restaurant_id": "1234"
}
),
InsertOne(
document={
"name": "Mongo's Deli",
"cuisine": "Sandwiches",
"borough": "Brooklyn",
"restaurant_id": "5678"
}
),
UpdateMany(
filter={ "name": "Mongo's Deli" },
update={ "$set": { "cuisine": "Sandwiches and Salads" }}
),
DeleteOne(
filter={ "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)

次の例では、MongoClientインスタンスで bulk_write() メソッドを使用して、sample_restaurants.restaurantssample_mflix.movies の名前空間に対して複数の書込み操作を実行します。

operations = [
InsertOne(
namespace="sample_mflix.movies",
document={
"title": "Minari",
"runtime": 217,
"genres": ["Drama", "Comedy"]
}
),
UpdateOne(
namespace="sample_mflix.movies",
filter={ "title": "Minari" },
update={ "$set": { "runtime": 117 }}
),
DeleteMany(
namespace="sample_restaurants.restaurants",
filter={ "cuisine": "French" }
)
]
results = client.bulk_write(operations)
print(results)
ClientBulkWriteResult({'anySuccessful': True, 'error': None, 'writeErrors': [],
'writeConcernErrors': [], 'nInserted': 1, 'nUpserted': 0, 'nMatched': 1,
'nModified': 1, 'nDeleted': 344, 'insertResults': {}, 'updateResults': {},
'deleteResults': {}}, acknowledged=True, verbose=False)

オプションで、bulk_write() メソッドは追加のパラメーターを受け入れます。これらのパラメーターは、 一括書込み操作を構成するために使用できるオプションを表します。

次の表では、Collection.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.
デフォルトは True です。

bypass_document_validation

Specifies whether the operation bypasses document-level validation. For more information, see Schema Validation in the MongoDB Server manual.
デフォルトは 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 はすべての操作を試行した後にのみエラーを報告します。

注意

順序なしの一括操作では、実行順序は保証されません。 この順序は、ランタイムを最適化するために一覧表示する方法とは異なる場合があります。

次の表では、MongoClient.bulk_write() メソッドに渡すことができるオプションについて説明しています。

プロパティ
説明

session

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

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.
デフォルトは True です。

verbose_results

Specifies whether the operation returns detailed results for each successful operation.
デフォルトは False です。

bypass_document_validation

Specifies whether the operation bypasses document-level validation. For more information, see Schema Validation in the MongoDB Server manual.
デフォルトは False です。

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.

write_concern

Specifies the write concern to use for the bulk operation. For more information, see Write Concern in the MongoDB Server manual.

次の例では、前述のクライアント一括書き込みの例から bulk_write() メソッドを呼び出しますが、verbose_results オプションを True に設定します。

results = client.bulk_write(operations, verbose_results=True)
ClientBulkWriteResult({'anySuccessful': True, 'error': None, 'writeErrors': [],
'writeConcernErrors': [], 'nInserted': 1, 'nUpserted': 0, 'nMatched': 1, 'nModified': 1,
'nDeleted': 344, 'insertResults': {0: InsertOneResult(ObjectId('...'),
acknowledged=True)}, 'updateResults': {1: UpdateResult({'ok': 1.0, 'idx': 1, 'n': 1,
'nModified': 1}, acknowledged=True)}, 'deleteResults': {2: DeleteResult({'ok': 1.0,
'idx': 2, 'n': 344}, acknowledged=True)}}, acknowledged=True, verbose=True)

このセクションでは、次の一括操作メソッドの戻り値について説明します。

Collection.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.bulk_write()メソッドはClientBulkWriteResultオブジェクトを返します。 ClientBulkWriteResultオブジェクトには次のプロパティが含まれています。

プロパティ
説明

acknowledged

Indicates if the server acknowledged the write operation.

bulk_api_result

The raw bulk API result returned by the server.

delete_results

A map of any successful delete operations and their results.

deleted_count

The number of documents deleted, if any.

has_verbose_results

Indicates whether the returned results are verbose.

insert_results

A map of any successful insert operations and their results.

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.

update_results

A map of any successful update operations and their results.

upserted_count

The number of documents upserted, if any.

MongoClientオブジェクトに型注釈を追加しない場合、型チェッカーに次のようなエラーが表示される場合があります。

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

解決策としては、MongoClientオブジェクトを client: MongoClient または client: 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 ドキュメントを参照してください。