AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
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コレクションに対して複数の書込み操作を実行します。対応するコードを表示するには、Synchronous タブまたは Asynchronousタブを選択します。

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)
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 = await 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 の名前空間に対して複数の書込み操作を実行します。対応するコードを表示するには、Synchronous タブまたは Asynchronousタブを選択します。

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)
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 = await 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

True の場合、ドライバーは指定された順序で書き込み操作を実行します。エラーが発生した場合、残りの操作は試行されません。

False の場合、ドライバーは操作を任意の順序で実行し、すべての操作を実行しようとします。
デフォルトは True です。

bypass_document_validation

操作がドキュメントレベルの検証をバイパスするかどうかを指定します。詳細については、 MongoDB Serverマニュアルの「 スキーマバリデーション 」を参照してください。デフォルトは
Falseです。

session

ClientSessionのインスタンス。詳細については、 APIドキュメント を参照してください。

comment

操作に添付するコメント。 詳細については、MongoDB Server マニュアルの 「削除コマンド フィールドのガイド」 を参照してください。

let

パラメーター名と値のマップ。 値は、ドキュメント フィールドを参照しない定数または閉じた式である必要があります。 詳細については、MongoDB Server マニュアルのlet ステートメントを参照してください。

次の例では、前述のコレクション一括書き込みの例からbulk_write() メソッドを呼び出しますが、ordered オプションをFalse に設定します。対応するコードを表示するには、Synchronous タブまたは Asynchronousタブを選択します。

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

順序なし一括書き込み 内のいずれかの書き込み操作が失敗した場合、PyMongo はすべての操作を試行した後にのみエラーを報告します。

注意

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

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

プロパティ
説明

session

ClientSessionのインスタンス。詳細については、 APIドキュメント を参照してください。

ordered

True の場合、ドライバーは指定された順序で書き込み操作を実行します。エラーが発生した場合、残りの操作は試行されません。

False の場合、ドライバーは操作を任意の順序で実行し、すべての操作を実行しようとします。
デフォルトは True です。

verbose_results

操作が成功させる各操作の詳細な結果を返すかどうかを指定します。
デフォルトは False です。

bypass_document_validation

操作がドキュメントレベルの検証をバイパスするかどうかを指定します。詳細については、 MongoDB Serverマニュアルの「 スキーマバリデーション 」を参照してください。デフォルトは
Falseです。

comment

操作に添付するコメント。 詳細については、MongoDB Server マニュアルの 「削除コマンド フィールドのガイド」 を参照してください。

let

パラメーター名と値のマップ。 値は、ドキュメント フィールドを参照しない定数または閉じた式である必要があります。 詳細については、MongoDB Server マニュアルのlet ステートメントを参照してください。

write_concern

一括操作に使用する書込み保証 (write concern)を指定します。詳細については、 MongoDB Serverマニュアルの「 書込み保証 」を参照してください。

次の例では、前述のクライアント一括書き込みの例からbulk_write() メソッドを呼び出しますが、verbose_results オプションをTrue に設定します。対応するコードを表示するには、Synchronous タブまたは Asynchronousタブを選択します。

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)
results = await 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

サーバーが書込み (write) 操作を確認したかどうかを示します。

bulk_api_result

サーバーによって返された未加工の一括API の結果です。

deleted_count

削除されたドキュメントの数(存在する場合)。

inserted_count

挿入されたドキュメントの数(存在する場合)。

matched_count

アップデートに一致したドキュメントの数(該当する場合)。

modified_count

変更されたドキュメントの数(存在する場合)。

upserted_count

アップサートされたドキュメントの数(存在する場合)。

upserted_ids

操作のインデックスとアップサートされたドキュメントの_idへのマップ(該当する場合)。

MongoClient.bulk_write()メソッドはClientBulkWriteResultオブジェクトを返します。 ClientBulkWriteResultオブジェクトには次のプロパティが含まれています。

プロパティ
説明

acknowledged

サーバーが書込み (write) 操作を確認したかどうかを示します。

bulk_api_result

サーバーによって返された未加工の一括API の結果です。

delete_results

成功した削除操作とその結果のマップ。

deleted_count

削除されたドキュメントの数(存在する場合)。

has_verbose_results

返される結果が詳細であるかどうかを示します。

insert_results

成功した挿入操作とその結果のマップ。

inserted_count

挿入されたドキュメントの数(存在する場合)。

matched_count

アップデートに一致したドキュメントの数(該当する場合)。

modified_count

変更されたドキュメントの数(存在する場合)。

update_results

成功した更新操作とその結果のマップ。

upserted_count

アップサートされたドキュメントの数(存在する場合)。

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 ドキュメントを参照してください。