Docs Menu

db.collection.bulkWrite()

MongoDB とドライバー

このページではmongoshメソッドがドキュメントされています。 MongoDB ドライバーで同等のメソッドを確認するには、プログラミング言語の対応するページを参照してください。

db.collection.bulkWrite()

実行順序の制御を使用して複数の書き込み操作を実行します。

次の値を返します。
  • 書込み保証付きで操作が実行された場合はacknowledged のブール値は true に、書込み保証が無効の場合は false になります。
  • 各書き込み操作のカウント。
  • 正常に挿入またはアップサートされた各ドキュメントの _id を含む配列。

db.collection.bulkWrite() は、以下の環境でホストされている配置で利用可能です。

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです

注意

このコマンドは、すべての MongoDB Atlas クラスターでサポートされています。すべてのコマンドに対する Atlas のサポートについては、「サポートされていないコマンド」を参照してください。

  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

注意

Atlas UI では一括書込み操作を実行できません。複数のドキュメントを挿入するには、ドキュメントの配列を挿入する必要があります。詳細については、Atlas ドキュメントの「ドキュメントの作成、表示、アップデート、および削除」を参照してください。

bulkWrite() メソッドの形式は次のとおりです。

db.collection.bulkWrite(
[ <operation 1>, <operation 2>, ... ],
{
writeConcern : <document>,
ordered : <boolean>
}
)

bulkWrite() メソッドは次のパラメーターを取ります。

Parameter
タイプ
説明

operations

配列

bulkWrite()書込み (write) 操作の配列

有効な操作は次のとおりです。

各操作の使用方法については、「 書込み操作 」を参照してください。

writeConcern

ドキュメント

任意。書込み保証(write concern)を表現するドキュメント。デフォルトの書込み保証を使用する場合は省略します。

トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。

ordered

ブール値

任意。mongod インスタンスで実行されるのが順序付き操作実行か、順序なし操作実行かを指定するブール値。デフォルトの値は true です。

操作の実行」を参照してください。

bulkWrite()書込み操作の配列を受け取り、それぞれを実行します。デフォルトでは、操作は順番に実行されます。書込み (write) 操作の実行順序を制御するには、「操作の実行」を参照してください。

コレクションに単一のドキュメントを挿入します。

db.collection.bulkWrite( [
{ insertOne : { "document" : <document> } }
] )

db.collection.insertOne() を参照してください。

updateOne は、コレクション内でフィルターに一致する 単一の ドキュメントをアップデートします。複数のドキュメントが一致する場合、updateOne最初に一致したドキュメントのみをアップデートします。

db.collection.bulkWrite( [
{ updateOne :
{
"filter": <document>,
"update": <document or pipeline>,
"upsert": <boolean>,
"collation": <document>,
"arrayFilters": [ <filterdocument1>, ... ],
"hint": <document|string>
}
}
] )

updateMany は、コレクション内でフィルターに一致するすべてのドキュメントをアップデートします。

db.collection.bulkWrite( [
{ updateMany :
{
"filter" : <document>,
"update" : <document or pipeline>,
"upsert" : <boolean>,
"collation": <document>,
"arrayFilters": [ <filterdocument1>, ... ],
"hint": <document|string>
}
}
] )
フィールド
ノート

filter

更新の選択基準。db.collection.find()メソッドと同じクエリ セレクターを使用できます。

update

実行されるアップデート操作。次のいずれかを指定できます。

upsert

任意。アップサートを実行するかどうかを示すブール値。

デフォルトでは、 upsertfalse です。

arrayFilters

任意。配列フィールドの更新操作でどの配列要素を変更するかを決定するフィルター ドキュメントの配列。

collation

任意。操作に使用する照合を指定します。

hint

任意。アップデート filter をサポートするために使用するインデックス。 存在しないインデックスを指定した場合、操作はエラーになります。

詳細については、db.collection.updateOne()db.collection.updateMany() を参照してください。

replaceOne は、コレクション内でフィルターに一致する単一のドキュメントを置き換えます。複数のドキュメントが一致する場合、replaceOne最初に一致したドキュメントのみを置換します。

db.collection.bulkWrite([
{ replaceOne :
{
"filter" : <document>,
"replacement" : <document>,
"upsert" : <boolean>,
"collation": <document>,
"hint": <document|string>
}
}
] )
フィールド
ノート

filter

置換操作の選択基準。db.collection.find() メソッドと同じクエリ セレクターが使用できます。

replacement

upsert

任意。アップサートを実行するかどうかを示すブール値。デフォルトでは、 upsertfalse です。

collation

任意。操作に使用する照合を指定します。

hint

任意。アップデート filter をサポートするために使用するインデックス。 存在しないインデックスを指定した場合、操作はエラーになります。

詳細については db.collection.replaceOne() を参照してください。

deleteOne は、コレクション内でフィルターに一致する単一のドキュメントを削除します。複数のドキュメントが一致する場合、deleteOne最初に一致したドキュメントのみを削除します。

db.collection.bulkWrite([
{ deleteOne : {
"filter" : <document>,
"collation" : <document> // Available starting in 3.4
} }
] )

deleteMany は、コレクション内でフィルターに一致するすべてのドキュメントを削除します。

db.collection.bulkWrite([
{ deleteMany: {
"filter" : <document>,
"collation" : <document> // Available starting in 3.4
} }
] )
フィールド
ノート

filter

削除操作の選択基準。db.collection.find() メソッドと同じクエリ セレクターが使用できます。

collation

任意。操作に使用する照合を指定します。

詳細については、db.collection.deleteOne()db.collection.deleteMany() を参照してください。

ドキュメントで _id フィールドが指定されていない場合は、 mongod_id フィールドが追加され、ドキュメントの挿入またはアップサートの前にユニークな ObjectId() が割り当てられます。ほとんどのドライバーでは ObjectId が作成され、 _id フィールドが挿入されますが、ドライバーやアプリケーションでこの処理が行われない場合は、 mongod_id の作成と入力が行われます。

ドキュメントに _id フィールドが含まれる場合に重複キー エラーを回避するには、_id 値がコレクション内で一意になるようにする必要があります。

更新操作または置換操作では、元のドキュメントと異なる _id 値を指定することはできません。

ordered パラメーターでは、bulkWrite() が順番に操作を実行するか指定します。デフォルトでは、操作は順番に実行されます。

次のコードは、5 つの操作を含む bulkWrite() を表します。

db.collection.bulkWrite(
[
{ insertOne : <document> },
{ updateOne : <document> },
{ updateMany : <document> },
{ replaceOne : <document> },
{ deleteOne : <document> },
{ deleteMany : <document> }
]
)

デフォルトである ordered : true の状態では、最初の操作 insertOne から最後の操作 deleteMany まで、各操作が順番に実行されます。

ordered が false に設定されている場合、パフォーマンスを向上させるために mongod によって操作の順序が並べ替えられることがあります。アプリケーションは操作の実行順序に依存すべきではありません。

次のコードは、6 つの操作を含む順序付けられていない bulkWrite() を表します。

db.collection.bulkWrite(
[
{ insertOne : <document> },
{ updateOne : <document> },
{ updateMany : <document> },
{ replaceOne : <document> },
{ deleteOne : <document> },
{ deleteMany : <document> }
],
{ ordered : false }
)

ordered : false の場合、操作の結果が異なる場合があります。たとえば、 deleteOne または deleteMany では、 insertOneupdateOneupdateManyreplaceOne の操作の前に実行されるか、後に実行されるかによって、削除されるドキュメントの数が増減する場合があります。

各グループ内の操作の数は、データベースの maxWriteBatchSize の値を超えることはできません。maxWriteBatchSize のデフォルト値は 100,000 です。この値は hello.maxWriteBatchSize フィールドに表示されます。

この制限により、エラー メッセージの肥大化の問題が回避されます。この制限を超えるグループがある場合、クライアント ドライバーによって、操作数が制限値以下となる小さなグループに分割されます。たとえば、maxWriteBatchSize の値が 100,000 の場合、キューに 200,000 回の操作が含まれていると、ドライバによってそれぞれの操作回数が 100,000 回となるグループが 2 個作成されます。

注意

ドライバーによってグループが複数の小さなグループに分割されるのは、ハイレベル API を使用している場合のみに限られます。db.runCommand() を直接使用する場合(たとえばドライバーを書き込む場合)、制限を超えるバッチ書込みを実行しようとすると、MongoDB ではエラーがスローされます。

1 つのバッチのエラーレポートが大きくなりすぎた場合、MongoDB では残りのすべてのエラーメッセージを切り捨てて空の文字列にします。少なくとも 2 つのエラーメッセージがあり、合計サイズが 1MB を超える場合、これらは切り捨てられます。

サイズとグループ化の仕組みは内部的パフォーマンスの細部に該当し、今後のバージョンで変更される可能性があります。

シャーディングされたコレクションで ordered 操作リストを実行すると、通常、 unordered リストの実行よりも時間がかかります。これは、ordered リストでは毎回の操作で前の操作の完了を待機する必要があるためです。

bulkWrite() 書き込み (write) 操作は、上限付きコレクションで使用する場合、制限があります。

update 条件によって変更されているドキュメントのサイズが増加する場合には、updateOneupdateMany によりWriteError がスローされます。

replacement ドキュメントのサイズが元のドキュメントよりも大きい場合は replaceOne により WriteError がスローされます。

deleteOnedeleteMany では、上限付きコレクションで使用された場合に WriteError がスローされます。

bulkWrite() 書込み (write) 操作は、時系列コレクションで使用する場合、制限があります。時系列コレクションで使用できるのは insertOne のみです。他のすべての操作は WriteError を返します。

db.collection.bulkWrite() は、エラー時に BulkWriteError 例外をスローします。「トランザクション内のエラー処理」を参照してください。

書込み保証( write concern ) エラーを除き、順序付き操作はエラーの発生後に停止します。一方、順序なし操作は、トランザクション内で実行されない限り、キューにある残りの書込み操作の処理を続行します。 「トランザクション内でのエラー処理 」を参照してください。

書込み保証エラーは writeConcernErrors フィールドに表示され、その他すべてのエラーは writeErrors フィールドに表示されます。エラーが発生した場合、挿入された_id 値の代わりに、成功した書き込み操作の数が表示されます。実行順序の決まった操作では、発生したエラーが 1 つだけ表示され、実行順序のない操作では 1 つの配列内のそれぞれのエラーが表示されます。

コレクションでスキーマ検証が使用されており、 validationActionerrorに設定されている場合、無効なドキュメントを挿入したり、無効な値を持つドキュメントを更新したりすると、エラーがスローされます。 operations配列内の無効な操作に先行する操作が実行され、 コレクションに書き込まれます。 orderedフィールドは、残りの操作が実行されるかどうかを決定します。

db.collection.bulkWrite()分散トランザクション内で使用できます。

重要

ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。

トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。

機能の互換性バージョン (FCV)"4.4" 以上の場合、存在しないコレクションに対してトランザクションで upsert: true を使用した挿入操作またはアップデート操作を実行すると、コレクションが暗黙的に作成されます。

注意

クロスシャードの書き込みトランザクションでは新しいコレクションを作成できません。たとえば、あるシャードで既存コレクションに書き込み、別のシャードで暗示的にコレクションを作成する場合、MongoDB では同じトランザクションで両方の操作を実行できません。

トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。

MongoDB4 .2 以降では、トランザクション内で db.collection.bulkWrite() 操作にエラーが発生した場合、メソッドは BulkWriteException をスローします (トランザクション外と同様)。

4.0 では、 bulkWrite 操作でトランザクション内のエラーが発生した場合、スローされたエラーは BulkWriteException としてはラップされません。

トランザクション内では、一括書き込みで最初のエラーが発生すると、順序付けがない場合であっても一括書き込み全体が失敗し、トランザクションが中止されます。

bulkWrite() 操作の順序とエラー処理を理解することが重要です。bulkWrite() はデフォルトで順序が付いたリストの操作を実行します。

  • 操作は連続して実行されます。

  • 操作にエラーがある場合、その操作および後続の操作は実行されません。

  • エラー操作が完了する前に一覧表示された操作。

bulkWrite() の例では、pizzas コレクションを使用します。

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )

次の 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: {}
}

前の bulkWrite() の例を実行する前に、コレクションに _id4 のドキュメントがすでに含まれていた場合、2 番目の insertOne 操作に対して以下の重複キー例外が返されます。

writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 4 }',
op: { _id: 4, type: 'sausage', size: 'large', price: 10 }
}
}
],
result: BulkWriteResult {
result: {
ok: 1,
writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 4 }',
op: { _id: 4, type: 'sausage', size: 'large', price: 10 }
}
}
],
writeConcernErrors: [],
insertedIds: [ { index: 0, _id: 3 }, { index: 1, _id: 4 } ],
nInserted: 1,
nUpserted: 0,
nMatched: 0,
nModified: 0,
nRemoved: 0,
upserted: []
}
}

bulkWrite() の例は順序付けられているため、最初の insertOne 操作のみが完了します。

エラーのないすべての操作を完了するには、orderedfalse に設定して bulkWrite() を実行します。例については、次のセクションを参照してください。

順序付けられていないbulkWrite() を指定するには、 orderedfalse に設定します。

順序付けられていない bulkWrite() の操作リストでは次のようになります。

  • 操作は並行して実行可能です(保証はされません)。詳細については順序付き操作と順序なし操作を参照してください。

  • エラーのある操作は完了しません。

  • エラーのないすべての操作が完了します。

pizzas コレクションの例を引き続き使用し、コレクションの削除と再作成を行います。

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )

次の例を参照してください。

  • bulkWrite()pizzas コレクションに対して順序のない操作を実行します。

  • 2番目の insertOne 操作の _id は 1 番目の insertOneと同じであるため、重複キー エラーが発生します。

try {
db.pizzas.bulkWrite( [
{ insertOne: { document: { _id: 3, type: "beef", size: "medium", price: 6 } } },
{ insertOne: { document: { _id: 3, 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 }
} }
],
{ ordered: false } )
} catch( error ) {
print( error )
}

出力例には、重複キー エラーと完了した操作の概要が含まれています。

writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 3 }',
op: { _id: 3, type: 'sausage', size: 'large', price: 10 }
}
}
],
result: BulkWriteResult {
result: {
ok: 1,
writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 3 }',
op: { _id: 3, type: 'sausage', size: 'large', price: 10 }
}
}
],
writeConcernErrors: [],
insertedIds: [ { index: 0, _id: 3 }, { index: 1, _id: 3 } ],
nInserted: 1,
nUpserted: 0,
nMatched: 2,
nModified: 2,
nRemoved: 1,
upserted: []
}
}

重複キー エラーのため、2 番目のinsertOne 操作は正常に実行されません。順序付けられていない bulkWrite()では、エラーのないすべての操作が完了します。

pizzas コレクションの例を引き続き使用し、コレクションの削除と再作成を行います。

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )

次の bulkWrite() の例では、 pizzas コレクションに対して操作を実行し、100 ミリ秒のタイムアウト"majority"書込み保証 (write concern) を設定します。

try {
db.pizzas.bulkWrite( [
{ updateMany: {
filter: { size: "medium" },
update: { $inc: { price: 0.1 } }
} },
{ updateMany: {
filter: { size: "small" },
update: { $inc: { price: -0.25 } }
} },
{ deleteMany: { filter: { size: "large" } } },
{ insertOne: {
document: { _id: 4, type: "sausage", size: "small", price: 12 }
} } ],
{ writeConcern: { w: "majority", wtimeout: 100 } }
)
} catch( error ) {
print( error )
}

レプリカ セット ノードの大半が操作を確認するまでの時間が wtimeout を超えると、この例では書込み保証エラーと完了した操作の概要が返されます。

result: BulkWriteResult {
result: {
ok: 1,
writeErrors: [],
writeConcernErrors: [
WriteConcernError {
err: {
code: 64,
codeName: 'WriteConcernTimeout',
errmsg: 'waiting for replication timed out',
errInfo: { wtimeout: true, writeConcern: [Object] }
}
}
],
insertedIds: [ { index: 3, _id: 4 } ],
nInserted: 0,
nUpserted: 0,
nMatched: 2,
nModified: 2,
nRemoved: 0,
upserted: [],
opTime: { ts: Timestamp({ t: 1660329086, i: 2 }), t: Long("1") }
}
}