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

Multikey Indexes

項目一覧

  • 互換性
  • マルチキー インデックスの作成
  • インデックスの限界
  • 一意のマルチキー インデックス
  • 制限

配列値を持つフィールドにインデックスを付けるために、MongoDB は配列内の一意の要素ごとにインデックス キーを作成します。 これらのマルチキーインデックスは、配列フィールドに対する効率的なクエリをサポートします。 マルチキー インデックスは、両方のスカラー値[1] を含む配列に対して構築できます [1] (例: 文字列、数値)ネストされたドキュメントをサポートします。 配列に同じ値のインスタンスが複数含まれている場合、インデックスには値のエントリが 1 つだけ含まれます。

''addr.zip'' フィールドのマルチキー インデックスの図。''addr.zip'' フィールドには、住所ドキュメントの配列が含まれます。住所ドキュメントには ”zip” フィールドが含まれています。
[1] スカラー値とは、埋め込みドキュメントでも配列でもない値を指します。

MongoDB Atlas でホストされている配置ではマルチキー インデックスを使用できます。

MongoDB Atlas でホストされている配置のインデックスの管理の詳細については、「インデックスの作成、表示、削除、および非表示 」を参照してください。

マルチキー インデックスを作成するには、 db.collection.createIndex()メソッドを使用します。

db.coll.createIndex( { <field>: < 1 or -1 > } )

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

注意

WiredTiger および インメモリ ストレージ エンジン のみ

マルチキー インデックスの場合、MongoDB は、どのインデックス付きフィールドがインデックスをマルチキー インデックスにするかを追跡します。 この情報を追跡することで、MongoDB クエリ エンジンはより厳しいインデックス限界を使用できるようになります。

インデックスがマルチキーの場合、インデックスの限界の計算は特別なルールに従います。 マルチキー インデックスの限界の詳細については、「 マルチキー インデックスの限界 」を参照してください

一意なインデックスの場合、一意の制約は単一のドキュメント内ではなく、コレクション内の個別のドキュメント全体に適用されます。

この制約は個別のドキュメントに適用されるため、一意の マルチキー インデックスの場合、ドキュメントに含まれる配列要素によって、そのドキュメントのインデックス キー値と別のドキュメントのインデックス キー値が重複していない限り、インデックス キー値の反復につながることがあります。

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

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

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

    { _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" }

    コレクションに複合マルチキー インデックス{ a: 1, b: 1 }a bを作成することはできません。 フィールドと フィールドは両方とも配列であるためです。

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

    以下のドキュメントを含むコレクション を考慮します:

    { _id: 1, a: [1, 2], b: 1, category: "A array" }
    { _id: 2, a: 1, b: [1, 2], category: "B array" }

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

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

フィールドがドキュメントの配列である場合は、埋め込みフィールドにインデックスを付けて複合インデックスを作成できます。 たとえば、次のドキュメントを含むコレクションで考えてみましょう。

{ _id: 1, a: [ { x: 5, z: [ 1, 2 ] }, { z: [ 1, 2 ] } ] }
{ _id: 2, a: [ { x: 5 }, { z: 4 } ] }

{ "a.x": 1, "a.z": 1 }で複合インデックスを作成できます。 最大1 つのインデックス付きフィールドが配列であるという制限も適用されます。

例については、「埋め込みドキュメントを含む配列のインデックス 」を参照してください。

Tip

以下も参照してください。

MongoDB 4.4の配列フィールドのソート動作が変更された結果として、マルチキー インデックスでインデックス付けされた配列でソートする場合、次の場合を除き、クエリプランにはブロッキングソートステージが含まれます。

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

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

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

ただし、 シャード キー インデックスが複合インデックスの プレフィックス である場合、他のキー(シャードキーの一部ではないキー)は、配列をインデックスします。 複合マルチキー インデックス はパフォーマンスに影響を与える可能性があります。

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

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

たとえば、以下のドキュメントのある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コレクションを考えてみます。

{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] }
{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] }
{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }

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

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

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

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

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

$expr では、 マルチキー インデックス はサポートされていません。

次のドキュメントを使用してsurveyコレクションを作成します。

db.survey.insertOne(
{ _id: 1, item: "ABC", ratings: [ 2, 5, 9 ] }
)

フィールドratingsにインデックスを作成します。

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

ratingsフィールドには配列が含まれているため、 ratingsのインデックスはマルチキーです。 マルチキー インデックスには、それぞれが同じドキュメントを指している次の 3 つのインデックス キーが含まれています。

  • 2,

  • 5

  • 9.

ネストされたオブジェクトを含む配列フィールドにマルチキー インデックスを作成できます。

次の形式のドキュメントを含むinventoryコレクションを考えてみましょう。

{
_id: 1,
item: "abc",
stock: [
{ size: "S", color: "red", quantity: 25 },
{ size: "S", color: "blue", quantity: 10 },
{ size: "M", color: "blue", quantity: 50 }
]
}
{
_id: 2,
item: "def",
stock: [
{ size: "S", color: "blue", quantity: 20 },
{ size: "M", color: "blue", quantity: 5 },
{ size: "M", color: "black", quantity: 10 },
{ size: "L", color: "red", quantity: 2 }
]
}
{
_id: 3,
item: "ijk",
stock: [
{ size: "M", color: "blue", quantity: 15 },
{ size: "L", color: "blue", quantity: 100 },
{ size: "L", color: "red", quantity: 25 }
]
}
...

次の操作では、 フィールドと フィールドにマルチキー インデックスが作成されます。stock.sizestock.quantity

db.inventory.createIndex( { "stock.size": 1, "stock.quantity": 1 } )

複合マルチキー インデックスは、次の例のように、インデックス付きフィールドの両方を含む述語と、インデックス プレフィックス"stock.size"のみを含む述語を含むクエリをサポートできます。

db.inventory.find( { "stock.size": "M" } )
db.inventory.find( { "stock.size": "S", "stock.quantity": { $gt: 20 } } )

MongoDBでマルチキー インデックスの限界を組み合わせる方法の詳細については、「 マルチキー インデックスの限界 」を参照してください。 複合インデックスとプレフィックスの動作の詳細については、「複合インデックスとプレフィックス 」を参照してください。

複合マルチキー インデックスは、次の例のようなソート操作もサポートできます。

db.inventory.find( ).sort( { "stock.size": 1, "stock.quantity": 1 } )
db.inventory.find( { "stock.size": "M" } ).sort( { "stock.quantity": 1 } )

複合インデックスとソート操作の動作の詳細については、「クエリ結果をソートするためにインデックスを使用する 」を参照してください。

戻る

複合