マルチキー インデックスは、配列値を含むフィールドからデータを収集してソートします。マルチキー インデックスにより、配列フィールドに対するクエリのパフォーマンスが向上します。
配列値を含むフィールドにインデックスを作成すると、MongoDB では自動的にそのインデックスがマルチキー インデックスに設定されます。
MongoDB では、スカラー値(文字列や数値など)と埋め込みドキュメントの両方を含む配列に対してマルチキー インデックスを作成できます。配列に同じ値のインスタンスが複数含まれている場合、インデックスには値のエントリが 1 つだけ含まれます。
マルチキー インデックスを作成するには、次のプロトタイプを使用します。
db.<collection>.createIndex( { <arrayField>: <sortOrder> } )
この画像は、 addr.zipフィールドのマルチキー インデックスを示しています。
MongoDB Atlas でホストされる配置用UIに複合インデックスを作成・管理できます。
ユースケース
アプリケーションが配列値を含むフィールドを頻繁にクエリする場合は、マルチキー インデックスを使用するとクエリのパフォーマンスが向上します。
例、moviesコレクション内のドキュメントには、各映画に関連付けられたジャンルの配列である genresフィールドが含まれています。特定のジャンルを持つ映画を定期的にクエリします。たとえば、Drama と Action の両方の映画をすべて検索します。
genres フィールドにインデックスを作成すると、このクエリのパフォーマンスを向上させることができます。genres には配列値が含まれているため、MongoDB はインデックスをマルチキー インデックスとして格納します。
はじめる
マルチキー インデックスを作成するには、以下を参照してください。
詳細
このセクションでは、マルチキー インデックスの技術的詳細と制限について説明します。
このページの例では、 sample_mflixサンプルデータセット のデータを使用します。このデータセットを自己管理型MongoDBデプロイにロードする 方法の詳細については、「サンプルデータセットをロードする 」を参照してください。サンプルデータベースに変更を加えた場合、このページの例を実行するには、データベースを削除して再作成する必要がある場合があります。
インデックスの限界
インデックス スキャンの限界は、クエリ中に検索するインデックスの部分を定義します。マルチキー インデックスの限界の計算は特別なルールに従います。詳細については、「マルチキー インデックスの限界」を参照してください。
Unique Multikey Indexes
ユニークなマルチキー インデックスでは、そのドキュメントのインデックスキー値が別のドキュメントのインデックスキー値と重複しない限り、インデックスキー値が繰り返される配列要素がドキュメントに含まれる場合があります。
この動作の詳細と例については、「複数の別個のドキュメント間での一意制約」を参照してください。
複合マルチキー インデックス
複合マルチキー インデックスでは、インデックス作成されたそれぞれのドキュメントに、値が配列であるインデックス付きフィールドを最大で 1 つ含めることができます。具体的な説明は以下の通りです。
インデックス仕様内の複数のフィールドが配列の場合、複合マルチキーインデックスを作成することはできません。
複合マルチキー インデックスがすでに存在する場合、この制限に違反するドキュメントを挿入することはできません。
例、moviesコレクションに複合マルチキーインデックス{ genres: 1, year: 1
} を作成できます。これは、各ドキュメントで、複合マルチキーインデックスでインデックス付けされた 1 つのフィールドのみが配列であるためです。 genres フィールドと year フィールドの両方の配列値を含むドキュメントはありません。
ただし、複合マルチキー インデックスの作成後、genres フィールドと year フィールドの両方が配列であるドキュメントを挿入しようとすると、挿入は失敗します。
ソート
配列フィールドに対して マルチキーインデックス を使ってソートを行う場合、以下の両方の条件を満たさない限り、クエリプランには インメモリソート ステージが含まれます:
すべてのソートフィールドのインデックスの限界は
[MinKey, MaxKey]です。マルチキー インデックスの付いたフィールドの境界には、ソート パターンと同じパス プレフィックスはありません。
シャードキー
マルチキー インデックスをシャードキー インデックスとして指定することはできません。
ただし、シャードキー インデックスが複合インデックスのプレフィックスである場合、末尾のキー(シャードキーには含まれない)のいずれかが配列にインデックスを付けると、複合インデックスが複合マルチキー インデックスになる場合があります。
ハッシュされたインデックス
ハッシュされたインデックスをマルチキーにすることはできません。
カバード クエリ
次の条件が満たされている場合、マルチキー インデックスはクエリをカバーできます。
クエリは配列フィールドを返しません(つまり、配列はクエリプロジェクションに含まれていません)。つまり、クエリをカバーするには、マルチキー インデックスが複合である必要があります。
クエリには
$elemMatchが含まれていません。このクエリは、対象となる他のすべてのクエリ要件を満たしています。
例、次の操作では、genres フィールドと title フィールドの moviesコレクションに複合マルチキーインデックスが作成されます。
db.movies.createIndex( { genres: 1, title: 1 } )
genres フィールドに配列値が含まれているため、上記のインデックスはマルチキーです。
インデックスは次のクエリをカバーします。
db.movies.find( { genres: 'Drama' }, { _id: 0, title: 1 } ).sort({ genres: 1 }).limit(5)
db.movies.find( { title: 'The Ace of Hearts', genres: 'Drama' }, { _id: 0, title: 1 } )
プロジェクションには genres 配列フィールドが含まれているため、インデックスは次のクエリをカバーしていません。
db.movies.find( { genres: 'Drama' }, { _id: 0, genres: 1 } ).limit(5)
配列フィールド全体に対するクエリ
クエリで配列全体の完全一致が指定されている場合、 MongoDB はマルチキーインデックスを使用して、その配列の最初の要素を含むドキュメントを検索します。ただし、インデックスのみを使用して配列全体を一致させることはできません。次に、 MongoDB は候補ドキュメントを取得し、それらをフィルタリングして、配列がクエリ配列と完全に一致するドキュメントのみを返します。
例、次の操作では、genresフィールドの moviesコレクションにマルチキーインデックスが作成されます。
db.movies.createIndex( { genres: 1 } )
次のクエリは、 genresフィールドが配列[ "Drama" ]であるドキュメントを検索します。
db.movies.find( { genres: 'Drama' }, { title: 1, genres: 1 } ).limit(5)
MongoDB ではマルチキー インデックスを使用して、 genres配列内の任意の位置に"Drama"を持つドキュメントを見つけることができます。次に、MongoDB でこれらのドキュメントが取得され、genres 配列がクエリ配列 [ "Drama" ] と等しいドキュメントがフィルタリングされます。
$expr
$expr 演算子はマルチキー インデックスをサポートしていません。
詳細
MongoDB でマルチキー インデックスの限界を組み合わせてパフォーマンスを向上させる方法については、「マルチキー インデックスの限界」を参照してください。
配列フィールドをクエリする方法については、以下を参照してください。