Overview
MongoDB、書込み (write) 操作を一括で実行する能力がクライアントに提供されます。MongoDB 8.0 以降では、複数のデータベースとコレクションにわたって一括書き込み操作を実行できます。MongoDB 8.0 より前のバージョンを使用している場合は、単一のコレクションに対して一括書き込み操作を実行できます。
MongoDB8.0 で複数のデータベースとコレクションにわたって一括書き込み操作を実行するには、bulkWrite
データベースコマンドまたはMongo.bulkWrite()
mongosh
メソッドを使用します。
単一のコレクションに対して一括書き込み操作を実行するには、db.collection.bulkWrite()
mongosh
メソッドを使用します。MongoDB 8.0 以降を実行中いる場合は、bulkWrite
または Mongo.bulkWrite()
を使用して 1 つのコレクションに書き込むこともできます。
順序付き操作と順序なし操作
一括書き込み操作は、順序付きまたは順序なしで設定できます。
MongoDBでは、順序付きの操作リストを使用し、操作を連続して実行します。いずれかの書込み操作の処理中にエラーが発生した場合、 MongoDB はリスト内の残りの書込み操作を処理せずに返します。
操作の順序付けられていないリストを使用すると、MongoDB は操作を並列に実行できますが、この動作は保証されません。いずれかの書込み操作の処理中にエラーが発生した場合、MongoDB はリスト内の残りの書込み操作の処理を続行します。
シャーディングされたコレクションで順序付きの操作リストを実行すると、通常、順序なしのリストの実行よりも時間がかかります。これは、順序付きのリストでは毎回のオペレーションで前のオペレーションの完了を待機する必要があるためです。
デフォルトでは 、すべての一括書込みコマンドとメソッドは順序付き操作を実行します。順序なし操作を指定するには、優先コマンドまたはメソッドを呼び出すときに、ordered
オプションを false
に設定します。各コマンドまたはメソッドの構文の詳細については、上記のリンク先のページを参照してください。
一括書込み (write) メソッド
すべての一括書き込みメソッドとコマンドは、次の書き込み操作をサポートしています。
1 つを挿入
更新 1
多数更新
replaceOne
deleteOne
deleteMany
お好みのコマンドまたはメソッドを呼び出すと、各書き込み操作が配列内のドキュメントとして渡されます。各コマンドまたはメソッドの構文の詳細については、上記のリンク先のページを参照してください。
例
db.collection.bulkWrite()
次のdb.collection.bulkWrite()
の例では、pizzas
コレクションに対して次の操作を実行します。
insertOne
を使用して 2 つのドキュメントを追加します。updateOne
を使用してドキュメントをアップデートします。deleteOne
を使用してドキュメントを削除します。replaceOne
を使用してドキュメントを置換します。
try { db.pizzas.bulkWrite( [ { insertOne: { document: { _id: 3, type: "beef", size: "medium", price: 6 } } }, { insertOne: { document: { _id: 4, type: "sausage", size: "large", price: 10 } } }, { updateOne: { filter: { type: "cheese" }, update: { $set: { price: 8 } } } }, { deleteOne: { filter: { type: "pepperoni"} } }, { replaceOne: { filter: { type: "vegan" }, replacement: { type: "tofu", size: "small", price: 4 } } } ] ) } catch( error ) { print( error ) }
完了した操作の概要を含む出力例を示します。
{ acknowledged: true, insertedCount: 2, insertedIds: { '0': 3, '1': 4 }, matchedCount: 2, modifiedCount: 2, deletedCount: 1, upsertedCount: 0, upsertedIds: {} }
その他の例については、「 db 」を参照してください。 コレクション.bulkWrite() の例。
Mongo.bulkWrite()
この例では、Mongo.bulkWrite()
を使用して、次の操作を順番に実行します。
は、
db.authors
コレクションにドキュメントを挿入しますは、
db.books
コレクションにドキュメントを挿入します前のドキュメントを更新します
db.getMongo().bulkWrite( [ { namespace: 'db.authors', name: 'insertOne', document: { name: 'Stephen King' } }, { namespace: 'db.books', name: 'insertOne', document: { name: 'It' } }, { namespace: 'db.books', name: 'updateOne', filter: { name: 'it' }, update: { $set: { year: 1986 } } } ], { ordered: true, bypassDocumentValidation: true } )
mongosh
は一括書込み (write) を順番に実行し、次のドキュメントを返します。
{ acknowledged: true, insertedCount: 2, matchedCount: 1, modifiedCount: 1, deletedCount: 0, upsertedCount: 0, insertResults: { '1': { insertedId: ObjectId('67ed8ce8efd926c84cab7945') }, '2': { insertedId: ObjectId('67ed8ce8efd926c84cab7946') } } updateResults: { '1': { matchedCount: 1, modifiedCount: 1, didUpsert: false } } }
シャーディングされたコレクションへの一括挿入に関する戦略
初期データの挿入やルーチン データのインポートをはじめとした大規模な一括挿入操作は、シャーディングされたクラスターのパフォーマンスに影響を与える可能性があります。一括挿入の場合は、次の方法を検討してください。
コレクションの事前分割
シャーディングされたコレクションが空で、シャードキーの最初のキーにハッシュされたシャーディングを使用していない場合、コレクションには最初のチャンクが 1 つだけあり、そのチャンクは 1 つのシャード上にあります。MongoDB は、データを受信し、利用可能なシャードにチャンクを分配するために時間を必要とします。このパフォーマンスコストを回避するには、シャーディングされたクラスターで範囲を作成して、コレクションを事前に分割します。
への順序なしの書き込み mongos
シャーディングされたクラスターへの書込みパフォーマンスを向上させるには、優先メソッドまたはコマンドを呼び出すときに、ordered
を false
に設定して、順序なしの一括書き込みを実行します。mongos
は、複数のシャードへの書き込みの同時送信を試行できます。空のコレクションの場合はまず、「シャードクラスタでのチャンクの分割」で説明されているように、コレクションを事前に分割します。
単調なスロットリングを避ける
挿入中にシャードキーが単調に増加した場合、挿入されたすべてのデータはコレクションの最後のチャンクに送られ、最終的には常に 1 つのシャードになります。したがって、クラスターの挿入キャパシティーが、その 1 つのシャードの挿入キャパシティーを超えることはありません。
挿入量が単一のシャードで処理できる量よりも大きく、シャードキーの単調な増加が避けられない場合は、アプリケーションに対する次の変更を検討してください。
シャードキーのバイナリ ビットを逆にします。これによって情報が保持され、挿入の順序と値の増加順序との相関が回避されます。
インサートを「シャッフル」するには、最初と最後の 16 ビット ワードを入れ替えます。
例
C++ を使用した次の例では、生成されたBSON ObjectIdの先頭と末尾の 16 ビット ワードを入れ替えて、単調に増加しないようにします。
using namespace mongo; OID make_an_id() { OID x = OID::gen(); const unsigned char *p = x.getData(); swap( (unsigned short&) p[0], (unsigned short&) p[10] ); return x; } void foo() { // create an object BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "name" << "jane" ); // now we may insert o into a sharded collection }
Tip
シャードキーの選択に関する情報は、「シャードキー」を参照してください。また、「 「シャードキーの内部」(特に「シャードキーの選択」)も参照してください。