Docs Menu
Docs Home
/
MongoDBマニュアル
/ /

Multikey Indexes

項目一覧

  • ユースケース
  • はじめる
  • 詳細
  • インデックスの限界
  • Unique Multikey Indexes
  • 複合マルチキー インデックス
  • ソート
  • シャードキー
  • ハッシュされたインデックス
  • カバード クエリ
  • 配列フィールド全体に対するクエリ
  • $expr
  • 詳細

マルチキー インデックスは、配列値を含むフィールドからデータを収集してソートします。マルチキー インデックスにより、配列フィールドに対するクエリのパフォーマンスが向上します。

マルチキーのタイプを明示的に指定する必要はありません。配列値を含むフィールドにインデックスを作成すると、MongoDB では自動的にそのインデックスがマルチキー インデックスに設定されます。

MongoDB では、スカラー値(文字列や数値など)と埋め込みドキュメントの両方を含む配列に対してマルチキー インデックスを作成できます。配列に同じ値のインスタンスが複数含まれている場合、インデックスには値のエントリが 1 つだけ含まれます。

マルチキー インデックスを作成するには、次のプロトタイプを使用します。

db.<collection>.createIndex( { <arrayField>: <sortOrder> } )

この画像は、 addr.zipフィールドのマルチキー インデックスを示しています。

''addr.zip'' フィールドのマルチキー インデックスの図。''addr.zip'' フィールドには、住所ドキュメントの配列が含まれます。住所ドキュメントには ”zip” フィールドが含まれています。

MongoDB Atlas でホストされる配置用UIに複合インデックスを作成・管理できます。

アプリケーションが配列値を含むフィールドを頻繁にクエリする場合は、マルチキー インデックスを使用するとクエリのパフォーマンスが向上します。

よくクエリされるフィールドにインデックスを作成すると、それらのクエリを対象とする可能性が高くなります。対象のクエリとは、ドキュメントを検査することなく、インデックスを使用して完全に満たすことができるクエリです。これにより、クエリのパフォーマンスが最適化されます。

たとえば、 studentsコレクション内のドキュメントには、学生が学期を通して取得したテストのスコアの配列であるtest_scoresフィールドが含まれています。上位の生徒、つまり少なくとも 5 つのtest_scores90 よりも大きい生徒のリストが定期的に更新されます。

test_scores フィールドにインデックスを作成すると、このクエリのパフォーマンスを向上させることができます。test_scores には配列値が含まれているため、MongoDB はインデックスをマルチキー インデックスとして格納します。

マルチキー インデックスを作成するには、以下を参照してください。

このセクションでは、マルチキー インデックスの技術的詳細と制限について説明します。

インデックス スキャンの限界は、クエリ中に検索するインデックスの部分を定義します。マルチキー インデックスの限界の計算は特別なルールに従います。詳細については、「マルチキー インデックスの限界」を参照してください。

ユニークなマルチキー インデックスでは、そのドキュメントのインデックスキー値が別のドキュメントのインデックスキー値と重複しない限り、インデックスキー値が繰り返される配列要素がドキュメントに含まれる場合があります。

この動作の詳細と例については、「複数の別個のドキュメント間での一意制約」を参照してください。

複合マルチキー インデックスでは、インデックス作成されたそれぞれのドキュメントに、値が配列であるインデックス付きフィールドを最大で 1 つ含めることができます。具体的な説明は以下の通りです。

  • インデックス仕様内の複数のフィールドが配列の場合、複合マルチキー インデックスを作成することはできません。例ば、このドキュメントを含むコレクションを考えてみます。

    { _id: 1, scores_spring: [ 8, 6 ], scores_fall: [ 5, 9 ] }

    複合マルチキー インデックス { scores_spring: 1, scores_fall: 1 } はインデックス内の両方のフィールドが配列であるため、作成できません。

  • 複合マルチキー インデックスがすでに存在する場合、この制限に違反するドキュメントを挿入することはできません。

    これらのドキュメントを含むコレクションを考えてみます。

    { _id: 1, scores_spring: [8, 6], scores_fall: 9 }
    { _id: 2, scores_spring: 6, scores_fall: [5, 7] }

    複合マルチキー インデックス { scores_spring: 1, scores_fall: 1 } を作成できるのは、各ドキュメントで、複合マルチキー インデックスでインデックス付けされた 1 つのフィールドのみが配列であるためです。scores_springフィールドとscores_fallフィールドの両方の配列値を含むドキュメントはありません。

    ただし、複合マルチキー インデックスの作成後、scores_spring フィールドと scores_fall フィールドの両方が配列であるドキュメントを挿入しようとすると、挿入は失敗します。

マルチキー インデックスでインデックスされた配列フィールドに基づいてソートする場合、次の両方が当てはまらない限り、クエリプランにはブロッキングソートステージが含まれます。

  • すべてのソートフィールドのインデックスの限界[MinKey, MaxKey]です。

  • マルチキー インデックスの付いたフィールドの境界には、ソート パターンと同じパス プレフィックスはありません。

マルチキー インデックスをシャードキー インデックスとして指定することはできません。

ただし、シャードキー インデックスが複合インデックスのプレフィックスである場合、末尾のキー(シャードキーには含まれない)のいずれかが配列にインデックスを付けると、複合インデックスが複合マルチキー インデックスになる場合があります。

ハッシュされたインデックスをマルチキーにすることはできません。

次の条件が満たされている場合、マルチキー インデックスはクエリをカバーできます。

  • クエリは配列フィールドを返しません(つまり、配列はクエリプロジェクションに含まれていません)。つまり、クエリをカバーするには、マルチキー インデックスが複合である必要があります。

  • クエリには $elemMatch が含まれていません。

  • このクエリは、対象となる他のすべてのクエリ要件を満たしています。

たとえば、以下のドキュメントのあるmatches コレクションを考えます。

db.matches.insertMany( [
{ name: "Joe", event: [ "open", "tournament" ] },
{ name: "Bill", event: [ "match", "championship" ] }
] )

matchesコレクションでは、 eventフィールドとnameフィールドに複合マルチキー インデックスがあります。

db.matches.createIndex( { event: 1, name: 1 } )

event フィールドに配列値が含まれているため、上記のインデックスはマルチキーです。

インデックスは次のクエリをカバーします。

db.matches.find(
{ event: 'championship' },
{ _id: 0, name: 1 }
)
db.matches.find(
{ name: 'Bill', event: 'championship' },
{ _id: 0, name: 1 }
)

プロジェクションには event 配列フィールドが含まれているため、インデックスは次のクエリをカバーしていません。

db.matches.find(
{ event: 'championship' },
{ _id: 0, event: 1 }
)

クエリ フィルターで配列全体の完全一致が指定されている場合、MongoDB はマルチキー インデックスを使用してクエリ配列の最初の要素を検索できますが、マルチキー インデックス スキャンを使用して配列全体を検索することはできません。

代わりに、マルチキー インデックスを使用してクエリ配列の最初の要素を検索した後、MongoDB は関連するドキュメントを取得し、配列がクエリの配列と一致するドキュメントをフィルタリングします。

たとえば、次のドキュメントを含むinventory コレクションを考えます。

db.inventory.insertMany( [
{ _id: 5, type: "food", item: "apple", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "banana", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "chocolate", ratings: [ 9, 5, 8 ] }
{ _id: 8, type: "food", item: "fish", ratings: [ 9, 5 ] }
{ _id: 9, type: "food", item: "grapes", ratings: [ 5, 9, 5 ] }
] )

inventoryコレクションでは、 ratingsフィールドにマルチキー インデックスがあります。

db.inventory.createIndex( { ratings: 1 } )

次のクエリは、 ratingsフィールドが配列[ 5, 9 ]であるドキュメントを検索します。

db.inventory.find( { ratings: [ 5, 9 ] } )

MongoDB ではマルチキー インデックスを使用して、 ratings配列内の任意の位置に5を持つドキュメントを見つけることができます。次に、MongoDB でこれらのドキュメントが取得され、ratings 配列がクエリ配列 [ 5, 9 ] と等しいドキュメントがフィルタリングされます。

$expr 演算子はマルチキー インデックスをサポートしていません。

戻る

並び替え順