Overview
コレクションにドキュメントを挿入し、複数の他のドキュメントを更新してから、ドキュメントを削除するシナリオを考えてみましょう。 個々のメソッドを使用する場合、各操作には独自のデータベース呼び出しが必要です。 このガイドでは、一括書き込み操作を使用して、1 回のデータベース呼び出しで複数の書き込み操作を実行する方法を説明します。
サンプル データ
このガイドの例では、 Atlas サンプル データセットの sample_restaurants.restaurantsコレクションを使用します。 MongoDB Atlas クラスターを無料で作成し、サンプル データセットをロードする方法については、 「PyMongo を使い始める 」チュートリアルを参照してください。
書込み (write) 操作を定義する
実行する書込み操作ごとに、次のいずれかの操作クラスのインスタンスを作成します。
InsertOneUpdateOneUpdateManyReplaceOneDeleteOneDeleteMany
次に、これらのインスタンスのリストをbulk_write()メソッドに渡します。
次のセクションでは、前述のクラスのインスタンスを作成して使用する方法を示します。
挿入操作
挿入操作を実行するには、 InsertOneのインスタンスを作成し、挿入するドキュメントを指定します。
次の例では、 InsertOneのインスタンスを作成しています。
operation = pymongo.InsertOne( { "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のインスタンスを作成し、次の引数を渡します。
コレクション内のドキュメントを照合するために使用される基準を指定するクエリフィルター
実行する更新操作。 更新操作の詳細については、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 以前の 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のインスタンスを作成する必要があります。
削除操作
ドキュメントを削除するには、 DeleteOneのインスタンスを作成し、削除するドキュメントを指定するクエリフィルターを渡します。 DeleteOneは、クエリフィルターに一致する最初のドキュメントのみを削除します。
次の例では、 DeleteOneのインスタンスを作成しています。
operation = pymongo.DeleteOne({ "restaurant_id": "5678" })
複数のドキュメントを削除するには、 DeleteManyのインスタンスを作成し、削除するドキュメントを指定するクエリフィルターを渡します。 DeleteManyは、クエリフィルターに一致するすべてのドキュメントを削除します。
次の例では、 DeleteManyのインスタンスを作成しています。
operation = pymongo.DeleteMany({ "name": "Mongo's Deli" })
bulk_write()メソッドを呼び出す
実行する操作ごとにクラス インスタンスを定義したら、これらのインスタンスのリストを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()メソッドは追加のパラメーターを受け入れます。これらのパラメーターは、一括書き込み操作を構成するために使用できるオプションを表します。 追加のオプションを指定しない場合、ドライバーは一括書き込み操作をカスタマイズしません。
プロパティ | 説明 |
|---|---|
| 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. |
| Specifies whether the operation bypasses document-level validation. For more
information, see Schema
Validation in the MongoDB
Server manual. Defaults to False. |
| An instance of ClientSession. For more information, see the API
documentation. |
| A comment to attach to the operation. For more information, see the delete command
fields guide in the
MongoDB Server manual. |
| 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. |
次の例では、 orderedオプションをFalseに設定して、前の例からbulk_write()メソッドを呼び出します。
results = restaurants.bulk_write(operations, ordered=False)
順序なし一括書き込み 内のいずれかの書き込み操作が失敗した場合、PyMongo はすべての操作を試行した後にのみエラーを報告します。
注意
順序なしの一括操作では、実行順序は保証されません。 この順序は、ランタイムを最適化するために一覧表示する方法とは異なる場合があります。
戻り値
bulk_write()メソッドはBulkWriteResultオブジェクトを返します。 BulkWriteResultオブジェクトには次のプロパティが含まれています。
プロパティ | 説明 |
|---|---|
| Indicates if the server acknowledged the write operation. |
| The raw bulk API result returned by the server. |
| The number of documents deleted, if any. |
| The number of documents inserted, if any. |
| The number of documents matched for an update, if applicable. |
| The number of documents modified, if any. |
| The number of documents upserted, if any. |
| 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: 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 ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。