MongoDB とドライバー
このページでは、 mongosh メソッドについて説明します。MongoDB ドライバーで同等のメソッドを確認するには、ご使用のプログラミング言語の対応するページを参照してください。
定義
db.collection.insertMany()コレクションに複数のドキュメントを挿入します。
次の値を返します。 次の要素を含むドキュメント:
ブール値は、操作が
acknowledged書込み保証( 書込み保証true(write concern)false)付きで実行された場合は に設定され、書込み保証 (write concern)が無効になっている場合は に設定されます。正常に挿入された各ドキュメントの
_id値を含むinsertedIds配列
互換性
このメソッドは、次の環境でホストされている配置で使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
注意
このコマンドは、すべての MongoDB Atlas クラスターでサポートされています。すべてのコマンドに対する Atlas のサポートについては、「サポートされていないコマンド」を参照してください。
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
db.collection.insertMany() の構文は次のとおりです。
db.collection.insertMany( [ <document 1> , <document 2>, ... ], { writeConcern: <document>, ordered: <boolean> } )
パラメーター
Parameter | タイプ | 説明 |
|---|---|---|
| ドキュメント | コレクションに挿入するドキュメントの配列。 |
| ドキュメント | 任意。書込み保証(write concern)を表現するドキュメント。デフォルトの書込み保証を使用する場合は省略します。 トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。 |
| ブール値 | 任意。 |
動作
ドキュメントの配列が与えられると、insertMany() は配列内の各ドキュメントをコレクションに挿入します。配列に指定できるドキュメントの数に制限はありません。
操作の実行
デフォルトでは、ドキュメントは提供された順序で挿入されます。
orderedがtrueに設定され、挿入に失敗した場合、サーバーはレコードの挿入を続行しません。orderedがfalseに設定されている場合に挿入に失敗しても、サーバーはレコードの挿入を続行します。パフォーマンスを向上させるために、ドキュメントはmongodによって並べ替えられる場合があります。使用するinsertMany()が順序付けられていない場合、アプリケーションは挿入順序に依存しません。
シャーディングされたコレクションで ordered 操作リストを実行すると、通常、 unordered リストの実行よりも時間がかかります。これは、ordered リストでは毎回の操作で前の操作の完了を待機する必要があるためです。
バッチ処理
ドライバーは、maxWriteBatchSize に従って、insertMany() 配列で指定されたドキュメントをバッチします。これは 100,000 となり、変更できません。たとえば、insertMany() 操作に 250,000 件のドキュメントが含まれている場合、ドライバーは 3 つのバッチを作成します。これは、 100,000 件のドキュメントを持つバッチが 2 つ、および50,000 件のドキュメントを持つバッチが 1 つで構成されます。
注意
ドライバーは、ハイレベル API を使用する場合にのみバッチ処理を実行します。db.runCommand() を直接使用する場合(たとえばドライバーを書き込む場合)、maxWriteBatchSize の制限を超える書き込みバッチを実行しようとすると、MongoDB はエラーを返します。
1 つのバッチのエラーレポートが大きくなりすぎた場合、MongoDB は残りのすべてのエラーメッセージを切り捨てます。サイズが 1MB を超えるエラーメッセージが少なくとも 2 つある場合、これらのメッセージは切り捨てられます。
サイズとグループ化の仕組みは内部的パフォーマンスの細部に該当し、今後のバージョンで変更される可能性があります。
コレクションと _id フィールドの作成
コレクションが存在しない場合、insertMany() によってコレクションが作成されます。
挿入するドキュメントに _id フィールドが指定されていない場合、mongod によって _id フィールドが追加され、ドキュメントに一意の ObjectId() が割り当てられます。ほとんどのドライバーでは ObjectId が作成され、 _id フィールドが挿入されますが、ドライバーやアプリケーションでこの処理が行われない場合は、 mongod で_id の作成と入力が行われます。
ドキュメントに _id フィールドが含まれる場合に重複キー エラーを回避するには、_id 値がコレクション内で一意になるようにする必要があります。
説明可能性
insertMany() db.collection.explain()は と互換性がありません。
Error Handling
挿入は BulkWriteError の例外をスローします。
書込み保証(write concern)エラーを除き、順序付き操作はエラーの発生後に停止します。一方、順序なし操作はキューにある残りの書込み操作の処理を続行します。
書込み保証(write concern)エラーは writeConcernErrors フィールドに表示され、その他すべてのエラーは writeErrors フィールドに表示されます。エラーが発生した場合、挿入された _id のリストではなく、正常に実行された書込み操作の数が表示されます。順序付き操作では、発生したエラーが 1 つのみ表示され、順序なし操作では 1 つの配列内のそれぞれのエラーが表示されます。
スキーマ検証エラー
コレクションでスキーマ検証が使用されており、 validationActionがerrorに設定されている場合、 insertMany()を使用して無効なドキュメントを挿入すると、 writeErrorがスローされます。 documents配列内の無効なドキュメントに先行するドキュメントは、 コレクションに書き込まれます。 残りの有効なドキュメントが挿入されるかどうかは、 orderedフィールドの値によって決まります。
トランザクション
insertMany() は分散トランザクション内で使用できます。
重要
ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。
トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。
トランザクションでのコレクション作成
トランザクションがクロスシャード間書込みトランザクション(write transaction)でない場合に、分散トランザクション内にコレクションとインデックスを作成できます。
トランザクションにないコレクションに挿入を指定すると、MongoDB は暗黙的にコレクションを作成します。
書込み保証とトランザクション
トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。
無作為データのパフォーマンスに関する考慮事項
インデックス フィールドで大量の無作為データ(例: ハッシュされたインデックス)の挿入操作が実行される場合、挿入パフォーマンスが低下することがあります。無作為データを一括挿入すると、無作為のインデックスエントリが作成され、インデックスのサイズが増大します。無作為な挿入ごとに別のインデックスエントリへのアクセスが必要なサイズにインデックスが達した場合、挿入により WiredTiger キャッシュがエビクションおよび置き換えられる率が上昇します。こうした場合、インデックスは完全にキャッシュされなくなり、ディスク上で更新されるため、パフォーマンスが低下します。
インデックス フィールドでの無作為データの一括挿入動作を向上させるには、次のいずれかを実行します。
インデックスを削除し、無作為データを挿入した後に再度作成します。
インデックスのない空のコレクションにデータを挿入します。
一括挿入後にインデックスを作成すると、メモリ内のデータがソートされ、すべてのインデックスに対して順序付き挿入が実行されます。
Oplog エントリ
MongoDBは、db.collection.bulkWrite()操作内に insertMany() や複数の insertOne() 命令など複数のドキュメントを挿入する操作を、oplog の単一エントリに統合します。操作が失敗した場合、その操作によって oplog にエントリが追加されることはありません。
例
このページの例では、sample_mflixサンプルデータセットのデータを使用します。このデータセットを自己管理型MongoDB配置にロードする方法の詳細については、サンプルデータセットをロードする を参照してください。サンプルデータベースに変更を加えた場合、このページの例を実行するには、データベースを削除して再作成する必要がある場合があります。
_id フィールドを指定せずに複数のドキュメントを挿入
次の例では、_id フィールドを持たない 3 つのドキュメントを moviesコレクションに挿入します。
db.movies.insertMany( [ { title: "Inception", year: 2010, genres: [ "Action", "Sci-Fi" ] }, { title: "The Matrix", year: 1999, genres: [ "Action", "Sci-Fi" ] }, { title: "Interstellar", year: 2014, genres: [ "Adventure", "Sci-Fi" ] } ] )
{ acknowledged: true, insertedIds: { '0': "...", '1': "...", '2': "..." } }
ドキュメントに _id が含まれていないため、mongod は各ドキュメント向けに _idフィールドを作成して追加し、そのフィールドに一意の ObjectId() 値を割り当てます。
ObjectId 値は、操作が実行されるマシンと時間に固有であるため、実際の値は例の値と異なる可能性があります。
_id フィールドを指定して複数のドキュメントを挿入
次の例では、 _idフィールドを指定するドキュメントを moviesコレクションに挿入しています。コレクション内では重複キー エラーを回避するために、_id の値は一意である必要があります。
db.movies.insertMany( [ { _id: 10, title: "Inception", year: 2010 }, { _id: 11, title: "The Matrix", year: 1999 }, { _id: 12, title: "Interstellar", year: 2014 } ] )
{ acknowledged: true, insertedIds: { '0': 10, '1': 11, '2': 12 } }
_id など、ユニークインデックスの構成キーに重複値を挿入すると、例外がスローされます。この例外を受け、既存の _id 値を持つドキュメントの挿入を試みます。
try { db.movies.insertMany( [ { _id: 13, title: "Inception", year: 2010 }, { _id: 13, title: "The Dark Knight", year: 2008 }, { _id: 14, title: "Interstellar", year: 2014 } ] ); } catch (e) { print (e); }
_id: 13 はすでにあるため、次の例外がスローされます。
BulkWriteError({ "writeErrors" : [ { "index" : 0, "code" : 11000, "errmsg" : "E11000 duplicate key error collection: sample_mflix.movies index: _id_ dup key: { : 13.0 }", "op" : { "_id" : 13, "title" : "The Dark Knight", "year" : 2008 } } ], "writeConcernErrors" : [ ], "nInserted" : 1, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] })
挿入されたドキュメントは 1 つであることに注意してください。_id: 13 の最初のドキュメントは正常に挿入されましたが、2 番目の挿入は失敗します。この操作では、残りのドキュメントはキューに挿入されません。
ordered を false に設定すると、残りのドキュメントで挿入操作が続行されます。
順序なし挿入
次の例では、_id フィールドと ordered: false を伴う複数のドキュメントを挿入しようとしています。ドキュメントの配列には、_id フィールドが重複している 2 つのドキュメントが含まれています。
try { db.movies.insertMany( [ { _id: 10, title: "Inception", year: 2010 }, { _id: 11, title: "The Matrix", year: 1999 }, { _id: 11, title: "Interstellar", year: 2014 }, { _id: 12, title: "Arrival", year: 2016 }, { _id: 13, title: "Blade Runner 2049", year: 2017 }, { _id: 13, title: "Ex Machina", year: 2014 }, { _id: 14, title: "Her", year: 2013 } ], { ordered: false } ) } catch (e) { print(e) }
MongoBulkWriteError: E11000 duplicate key error collection: sample_mflix.movies index: _id_ dup key: { _id: 11 } Result: BulkWriteResult { insertedCount: 5, matchedCount: 0, modifiedCount: 0, deletedCount: 0, upsertedCount: 0, upsertedIds: {}, insertedIds: { '0': 10, '1': 11, '3': 12, '4': 13, '6': 14 } } Write Errors: [ WriteError { err: { index: 2, code: 11000, errInfo: undefined, errmsg: 'E11000 duplicate key error collection: sample_mflix.movies index: _id_ dup key: { _id: 11 }' } }, WriteError { err: { index: 5, code: 11000, errInfo: undefined, errmsg: 'E11000 duplicate key error collection: sample_mflix.movies index: _id_ dup key: { _id: 13 }' } } ]
title: "Interstellar" と title: "Ex Machina" を持つドキュメントの挿入は、_id 値が重複しているため、失敗しますが、insertedCount は残りの 5 ドキュメントが正常に挿入されていることを示しています。
書込み保証の使用
3つのノードから成るレプリカセットにおいて、次の操作は w の majority と wtimeout の 100 を指定します。
try { db.movies.insertMany( [ { _id: 15, title: "Forrest Gump", year: 1994 }, { _id: 16, title: "Schindler's List", year: 1993 }, { _id: 17, title: "Pulp Fiction", year: 1994 } ], { w: "majority", wtimeout: 100 } ); } catch (e) { print (e); }
プライマリと少なくとも 1 つのセカンダリが 100 ミリ秒以内に各書き込み操作を確認すると、次の値が返されます。
{ "acknowledged" : true, "insertedIds" : [ ObjectId("562a94d381cb9f1cd6eb0e1a"), ObjectId("562a94d381cb9f1cd6eb0e1b"), ObjectId("562a94d381cb9f1cd6eb0e1c") ] }
レプリカセット内ですべての必須ノードによる書き込み (write) 操作の確認に必要な合計時間が wtimeout を超過した場合、wtimeout 期間が経過すると次の writeConcernError が表示されます。
この操作では以下が返されます。
WriteConcernError({ "code" : 64, "errmsg" : "waiting for replication timed out", "errInfo" : { "wtimeout" : true, "writeConcern" : { "w" : "majority", "wtimeout" : 100, "provenance" : "getLastErrorDefaults" } } })