インデックスは、コレクション内のフィールドにすばやくアクセスできるようにすることで、データの取得速度を向上させる構造体です。 これらは、多くの場合、キー フィールドに基づいて、データへのポインターの順序付けされたセットを作成することによって機能します。 Azure DocumentDB では、クエリのプッシュダウン、一意の制約、シャーディングなど、複数のコンテキストでインデックスを利用します。
Important
"_id" フィールドは、既定でインデックスが作成された 唯一 のフィールドであり、フィールドの最大サイズは 2 KBできます。 パフォーマンスを最適化するために、クエリ フィルターと述語に基づいてインデックスを追加することをお勧めします。
インデックスの種類
わかりやすくするために、次のセットアップを使用したブログ アプリケーションの例を考えてみましょう。
-
データベース名:
cosmicworks -
コレクション名:
products
この例のアプリケーションでは、次の構造を持つドキュメントとしてアーティクルを格納します。 引用符で囲まれたすべての例では、このコレクションの構造をさらに利用します。
{
"_id": ObjectId("617a34e7a867530bff1b2346"),
"title": "Azure DocumentDB - A Game Changer",
"content": "Azure DocumentDB is a globally distributed, multi-model database service.",
"author": {lastName: "Doe", firstName: "John"},
"category": "Technology",
"launchDate": ISODate("2024-06-24T10:08:20.000Z"),
"published": true
}
単一フィールド インデックス
単一フィールド インデックスは、コレクション内の 1 つのフィールドからの情報を格納します。 単一フィールドのインデックスの並べ替え順序は重要ではありません。
_id フィールドは既定でインデックス付きのままです。
Azure DocumentDB では、次のインデックスの作成がサポートされています
- 最上位レベルのドキュメント フィールド。
- 埋め込みドキュメント。
- 埋め込みドキュメント内のフィールド。
次のコマンドは、フィールド author に 1 つのフィールド インデックスを作成し、次のコマンドは埋め込みフィールド firstNameに作成します。
use cosmicworks
db.products.createIndex({"author": 1})
// indexing embedded property
db.products.createIndex({"author.firstName": -1})
1 つのクエリでは、使用可能な場合は複数の単一フィールド インデックスを使用できます。
注
Azure DocumentDB では、コレクションに最大 64 個のインデックスを作成できます。 レベルに応じて、要求に応じて最大 300 個のインデックスの拡張を計画できます。
複合インデックス
複合インデックスは、ドキュメント内の複数のフィールドに基づいて 効率的なクエリと並べ替えを 行うことで、データベースのパフォーマンスを向上させます。 この最適化により、コレクション全体をスキャンする必要が減り、データの取得と編成が高速化されます。
次のコマンドは、フィールド author と launchDate に複合インデックスを作成し、これらのフィールドが逆の並べ替え順序でソートされます。
use cosmicworks
db.products.createIndex({"author":1, "launchDate":-1})
Order フィールドは選択性やインデックスの使用率に影響を与えます。
find クエリでは、作成されたインデックスは使用されません。
use cosmicworks
db.products.find({"launchDate": {$gt: ISODate("2024-06-01T00:00:00.000Z")}})
制限事項
- 複合インデックス内の最大 32 個のフィールド\パス。
部分インデックス
インデックスに用語を生成するタイミングを説明するクエリ フィルターが関連付けられているインデックス。
use cosmicworks
db.products.createIndex (
{ "author": 1, "launchDate": 1 },
{ partialFilterExpression: { "launchDate": { $gt: ISODate("2024-06-24T10:08:20.000Z") } } }
)
制限事項
- 部分インデックスでは、フィルターが修飾されない限り、
ORDER BYまたはUNIQUEはサポートされません。
テキスト インデックス
テキスト インデックスは、テキスト ベースのクエリを最適化し、より高速で効率的な特殊なデータ構造です。
createIndex フィールドにテキスト インデックスを作成するには、text オプションで title メソッドを使用します。
use cosmicworks;
db.products.createIndex({ title: "text" })
注
コレクションごとに定義できるテキスト インデックスは 1 つだけですが、Azure DocumentDB では、複数のフィールドの組み合わせに対してテキスト インデックスを作成して、ドキュメント内の異なるフィールド間でテキスト検索を実行できます。
テキスト インデックス オプションを構成する
Azure DocumentDB のテキスト インデックスには、動作をカスタマイズするためのオプションがいくつか用意されています。 たとえば、テキスト分析の言語を指定したり、特定のフィールドに優先順位を付ける重みを設定したり、大文字と小文字を区別しない検索を構成したりできます。 オプションを使用してテキスト インデックスを作成する例を次に示します。
英語がサポートされている
titleフィールドとcontentフィールドの両方で検索をサポートするインデックスを作成します。 また、titleフィールドに高い重みを割り当てて、検索結果で優先順位を付けます。use cosmicworks db.products.createIndex( { title: "text", content: "text" }, { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false } )
注
クライアントが "DocumentDB" という用語を使用してテキスト検索クエリを実行すると、コレクション内の各ドキュメントのスコアは、"title" フィールドと "content" フィールドの両方の用語の存在と頻度に基づいて計算され、"title" フィールドには重みが大きいため、重要度が高くなります。
テキスト インデックスを使用してテキスト検索を実行する
テキスト インデックスが作成されたら、クエリで "text" 演算子を使用してテキスト検索を実行できます。 テキスト演算子は検索文字列を受け取り、テキスト インデックスと照合して関連するドキュメントを検索します。
フレーズ
DocumentDBのテキスト検索を実行します。use cosmicworks db.products.find( { $text: { $search: "DocumentDB" } } )必要に応じて、
$metaプロジェクション演算子とクエリのtextScoreフィールドを使用して重みを確認しますuse cosmicworks db.products.find( { $text: { $search: "DocumentDB" } }, { score: { $meta: "textScore" } } )
制限事項
- コレクションに定義できるテキスト インデックスは 1 つだけです。
- 並べ替え操作では、MongoDB のテキスト インデックスの順序を使用できません。
- Hint() は、$text式を使用したクエリと組み合わせてサポートされていません。
- テキスト インデックスは比較的大きくなる可能性があります。他のインデックスの種類と比較して、大量のストレージ領域を消費します。
WildCard インデックス
1 つのフィールドのインデックスを作成し、同じレベルにある他のフィールドを除き、 field の下にあるすべてのパスにインデックスを付けます。 たとえば、次のサンプル ドキュメントの場合
{
"children":
{
"familyName": "Merriam",
"pets": { "details": {“name”: "Goofy", ”age”: 3} }
}
}
{ "pets.$**": 1 } にインデックスを作成すると、詳細プロパティとサブドキュメント プロパティにインデックスが作成されますが、"familyName" にインデックスは作成されません。
制限事項
- ワイルドカード インデックスでは、一意のインデックスをサポートできません。
- ワイルドカード インデックスでは、フィルターにワイルドカードに存在するパスのみが含まれていない限り、
ORDER BYのプッシュダウンはサポートされません (未定義の要素にインデックスを付けないため) - 複合ワイルドカード インデックスには、
oneワイルドカード用語とone以上のインデックス用語のみを含めることができます。{ "pets.$**": 1, “familyName”: 1 }
地理空間のインデックス
地理空間インデックスは、GeoJSON オブジェクトまたは従来の座標ペアとして格納されたデータに対するクエリをサポートします。 地理空間インデックスを使用すると、地理空間データに対するクエリのパフォーマンスを向上させたり、特定の地理空間クエリを実行したりできます。
Azure DocumentDB には、次の 2 種類の地理空間インデックスが用意されています。
- 2dsphere インデックス。球のジオメトリを解釈するクエリをサポートします。
- 2d インデックス。フラットサーフェス上のジオメトリを解釈するクエリをサポートします。
2D インデックス
2d インデックスは、地理空間データを格納する従来の座標ペア スタイルでのみサポートされます。
createIndex フィールドに地理空間インデックスを作成するには、2d オプションで location メソッドを使用します。
db.places.createIndex({ "location": "2d"});
制限事項
-
oneインデックスの一部にできるのは2d場所フィールドのみであり、他の地理空間フィールドonecompound 2dインデックスの一部にすることはできませんdb.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })
2dsphere インデックス
2dsphere インデックスは、地球に似た球に対する地理空間クエリをサポートします。 GeoJSON オブジェクトと従来の座標ペアの両方をサポートできます。
2dSphere インデックスは、データを格納する GeoJSON スタイルで動作します。レガシ ポイントが検出された場合は、GeoJSON ポイントに変換されます。
createIndex フィールドに地理空間インデックスを作成するには、2dsphere オプションで location メソッドを使用します。
db.places.createIndex({ "location": "2dsphere"});
2dsphere インデックスを使用すると、複数の地理空間データ フィールドと複数の非地理空間データ フィールドにインデックスを作成できます。
db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })
制限事項
通常のインデックスと地理空間インデックスを使用する複合インデックスはサポートされていません。 地理空間インデックスのいずれかを作成すると、エラーが発生します。
// Compound Regular & 2dsphere indexes are not supported yet db.collection.createIndex({a: 1, b: "2dsphere"}) // Compound 2d indexes are not supported yet db.collection.createIndex({a: "2d", b: 1})穴がある多角形は機能しません。 ホールのある Polygon の挿入は制限されませんが、
$geoWithinクエリはシナリオで失敗します。クエリ自体に穴のある多角形がある場合
coll.find( { "b": { "$geoWithin": { "$geometry": { "coordinates": [ [ [ 0, 0], [0, 10], [10, 10],[10,0],[0, 0] ], [ [5, 5], [8, 5], [ 8, 8], [ 5, 8], [ 5, 5] ] ], "type": "Polygon" } } } }) // MongoServerError: $geoWithin currently doesn't support polygons with holesフィルター処理されていないドキュメントに、穴のある多角形がある場合。
[mongos] test> coll.find() [ { _id: ObjectId("667bf7560b4f1a5a5d71effa"), b: { type: 'Polygon', coordinates: [ [ [ 0, 0 ], [ 0, 10 ], [ 10, 10 ], [ 10, 0 ], [ 0, 0 ] ], [ [ 5, 5 ], [ 8, 5 ], [ 8, 8 ], [ 5, 8 ], [ 5, 5 ] ] ] } } ] // MongoServerError: $geoWithin currently doesn't support polygons with holeskeyフィールドは、geoNearの使用中は必須です。[mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }]) // MongoServerError: $geoNear requires a 'key' option as a String
次のステップ
- 最も効率的な結果を得るためのインデックス作成の ベスト プラクティス について説明します。
- バックグラウンド インデックス作成の詳細
- テキスト インデックス作成を使用する方法については、こちらをご覧ください。
- ワイルドカードのインデックス作成については、こちらをご覧ください。