MongoDBは複合インデックスをサポートしており、1 つのインデックス構造がコレクションのドキュメント内の複数のフィールド[1]への参照を保持します。 以下の図は、2 つのフィールドの複合インデックスの例を示しています。
| [1] | MongoDBは、任意の複合インデックスに対して32フィールドの制限を課します。 |
複合インデックスは、複数のフィールドに一致するクエリをサポートできます。
互換性
MongoDB Atlasにホストされている配置には複合インデックスを使用できます。
MongoDB Atlas でホストされている配置のインデックスの管理の詳細については、「インデックスの作成、表示、削除、および非表示 」を参照してください。
複合インデックスの作成
複合インデックスを作成するには、次のプロトタイプのような操作を使用します。
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )
インデックス フィールドの順序は、特定のクエリに対する特定のインデックスの有効性に大きな影響を与えます。 ほとんどの複合インデックスでは、 ESR(Equality、Sort、Range)ルールに従うと、効率的なインデックスを作成するのに役立ちます。
重要
MongoDB 4.4 以降:
複合インデックスには、単一のハッシュされたインデックス フィールド を含めることができます。
MongoDB 4.2 またはそれ以前の場合は、
複合インデックスには、 ハッシュされたインデックス フィールド を含めることはでき ません 。
次のドキュメントのようなドキュメントを含む productsという名前のコレクションについて考えてみましょう。
{ "_id": ObjectId(...), "item": "Banana", "category": ["food", "produce", "grocery"], "location": "4th Street Store", "stock": 4, "type": "cases" }
次の操作では、 フィールドと フィールドに昇順のインデックスが作成されます。itemstock
db.products.createIndex( { "item": 1, "stock": 1 } )
複合インデックスにリストされるフィールドの順序は重要です。 インデックスには、 itemフィールドの値で最初にソートされ、 itemフィールドの各値内では 株式フィールドの値でソートされたドキュメントへの参照が含まれます。 詳細については、「ソート順序」を参照してください。
複合インデックスは、すべてのインデックス フィールドに一致するクエリをサポートするだけでなく、インデックス フィールドのプレフィックスに一致するクエリをサポートできます。 つまり、インデックスはitem フィールドと、item フィールドとstock フィールドの両方に対するクエリをサポートしています。
db.products.find( { item: "Banana" } ) db.products.find( { item: "Banana", stock: { $gt: 5 } } )
詳細については、「プレフィックス 」を参照してください。
並び替え順
インデックスには、フィールドへの参照が昇順( 1 )または降順( -1 )のソート順序で保存されます。 単一フィールド インデックスの場合、MongoDB はどちらの方向にもインデックスをトラバースできるため、キーのソート順序は重要ではありません。 ただし、複合インデックスの場合、ソート順序がインデックスでソート操作をサポートできるかどうかの判断で重要になる場合があります。
フィールドusernameとdateを持つドキュメントを含むコレクションeventsについて考えます。 アプリケーションは、最初にusername値の昇順でソートされ、次に (直近のdate値の降順)ソートされた結果を返すクエリを発行できます。たとえば、次のようなクエリを発行できます。
db.events.find().sort( { username: 1, date: -1 } )
または クエリのように、最初にusername値の降順でソートされ、次にdate値の昇順でソートされた結果を返すクエリは、次のようになります。
db.events.find().sort( { username: -1, date: 1 } )
次のインデックスは、これらの両方のソート操作をサポートできます。
db.events.createIndex( { "username" : 1, "date" : -1 } )
ただし、上記のインデックスでは、次のようなusername値の昇順、その後にdate値の昇順によるソートをサポートしていません。
db.events.find().sort( { username: 1, date: 1 } )
ソート順序と複合インデックスの詳細については、「クエリ結果をソートするためにインデックスを使用する 」を参照してください。
プレフィックス
インデックスのプレフィックスは、インデックス フィールドの開始サブセットです。 たとえば、次の複合インデックスについて考えてみます。
{ "item": 1, "location": 1, "stock": 1 }
インデックスには以下のようなプレフィックスがあります。
{ item: 1 }{ item: 1, location: 1 }
複合インデックスの場合、MongoDB はインデックスを使用してインデックス プレフィックスに対するクエリをサポートできます。 そのため、MongoDB は次のフィールドに対するクエリにインデックスを使用できます。
itemフィールドitemフィールドとlocationフィールドitemフィールドとlocationフィールドとstockフィールド
MongoDB では、 itemフィールドがプレフィックスに対応しているため、インデックスを使用してitemフィールドとstockフィールドに対するクエリをサポートすることもできます。 ただし、この場合、インデックスがitemとstockのみにある場合のように、インデックスはクエリをサポートする際に効率的ではありません。 インデックス フィールドは順番に解析されます。クエリで特定のインデックス プレフィックスが省略された場合、そのプレフィックスに続くインデックス フィールドは使用できません。
itemとstockのクエリではlocationインデックス プレフィックスが省略されるため、 location stockインデックス フィールドは使用できません。 このクエリをサポートできるのはインデックス内のitemフィールドのみです。 詳細については、 「 クエリをサポートするインデックスの作成」を参照してください。
MongoDB では、 itemフィールドがない場合、リストされたフィールドはいずれもプレフィックス インデックスに対応しないため、インデックスを使用して次のフィールドを含むクエリをサポートすることはできません。
locationフィールドstockフィールド、またはlocationフィールドとstockフィールド。
複合インデックスとそのプレフィックスの両方を持つコレクションがある場合(例: { a: 1, b: 1 }と{ a: 1 } )の場合、どちらのインデックスにも スパース 性の制約または 一意の 制約がない場合は、プレフィックスのインデックスを除くことができます(例: { a: 1 } )。 MongoDB では、プレフィックス インデックスを使用していたであろうすべての状況で複合インデックスが使用されます。
インデックスの交差
バージョン 2.6 以降では、MongoDB はインデックスの交差を使用してクエリを実行できます。 クエリをサポートする複合インデックスを作成するか、インデックスの交差に依存するかは、システムの仕様によって異なります。 詳細については、「インデックスの交差と複合インデックス」を参照してください。
スパース複合インデックス
複合インデックスには、さまざまなタイプのスパースインデックスを含めることができます。インデックスのタイプの組み合わせによって、複合インデックスがドキュメントと一致する方法が決まります。
下表には、さまざまなタイプのスパースインデックスを含む複合インデックスの動作がまとめられています。
複合インデックスの構成要素 | 複合インデックスの動作 |
|---|---|
Ascending indexes Descending indexes | 1 つ以上のキーの値を含むドキュメントのみ、インデックスが作成されます。 |
| |
|
その他の考慮事項
インデックスの構築中に、アプリケーションはインデックスが作成されるコレクションへのパフォーマンスの低下や読み取り/書き込みアクセスの制限が発生することがあります。
インデックス構築プロセスの詳細については、「入力済みコレクションでのインデックス構築 」、特に「 レプリケートされた環境でのインデックス構築 」セクションを参照してください。
一部のドライバーは、インデックス順序を指定するために、NumberLong(1) ではなく1 を使用します。結果として得られるインデックスは同じです。