適用対象: MongoDB 仮想コア
インデックスは、コレクション内のフィールドにすばやくアクセスできるようにすることで、データの取得速度を向上させる構造体です。 これらは多くの場合、キー フィールドに基づいて、データへのポインターの順序付けされたセットを作成することによって機能します。 Azure Cosmos DB for MongoDB 仮想コアは、クエリのプッシュダウン、一意の制約、シャーディングなど、複数のコンテキストでインデックスを利用します。
重要
"_id" フィールドは、既定でインデックス付けされる唯一のフィールドです。フィールドの取り得る最大サイズは 2 KB
です。 パフォーマンスを最適化するには、クエリ フィルターと述語に基づいてインデックスを追加することをお勧めします。
インデックスの種類
わかりやすくするために、次のセットアップを使用するブログ アプリケーションの例を考えてみましょう。
- データベース名:
cosmicworks
- コレクション名:
products
このアプリケーション例では、次の構造を持つドキュメントとしてアーティクルを格納します。 引用するすべての例では、このコレクションの構造をさらに利用します。
{
"_id": ObjectId("617a34e7a867530bff1b2346"),
"title": "Azure Cosmos DB - A Game Changer",
"content": "Azure Cosmos DB 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 Cosmos DB for MongoDB 仮想コアでは、次のインデックスの作成がサポートされています
- 最上位レベルのドキュメント フィールド。
- 埋め込みドキュメント。
- 埋め込みドキュメント内のフィールド。
次のコマンドは、フィールド author
に単一フィールド インデックスを作成し、その次のコマンドは埋め込みフィールド firstName
に作成します。
use cosmicworks
db.products.createIndex({"author": 1})
// indexing embedded property
db.products.createIndex({"author.firstName": -1})
可能な場合は、1 つのクエリで複数の単一フィールドのインデックスを使用できます。
注意
Azure Cosmos DB for MongoDB 仮想コアでは、コレクションに最大 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 Cosmos DB for MongoDB 仮想コアでは、複数のフィールドの組み合わせにテキスト インデックスを作成して、ドキュメント内の異なるフィールド間でテキスト検索を実行できます。
テキスト インデックス オプションを構成する
Azure Cosmos DB for MongoDB 仮想コアのテキスト インデックスには、動作をカスタマイズするためのいくつかのオプションが用意されています。 たとえば、テキスト分析用の言語を指定したり、特定のフィールドに優先順位を付ける重みを設定したり、大文字と小文字を区別しない検索を構成したりできます。 オプションを使用してテキスト インデックスを作成する例を次に示します。
英語をサポートする
title
およびcontent
フィールドの両方で検索をサポートするインデックスを作成します。 また、検索結果で優先順位を付けるために、title
フィールドに高い重みを割り当てます。use cosmicworks db.products.createIndex( { title: "text", content: "text" }, { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false } )
注意
クライアントが "Cosmos DB" という用語を使用してテキスト検索クエリを実行すると、コレクション内の各ドキュメントのスコアは、"title" フィールドと "content" フィールドの両方の用語の存在と頻度に基づいて計算されます ("title" フィールドは重みが大きいため、重要度が高くなります)。
テキスト インデックスを使用してテキスト検索を実行する
テキスト インデックスが作成されたら、クエリで "text" 演算子を使用してテキスト検索を実行できます。 テキスト演算子は検索文字列を取得し、テキスト インデックスと照合して関連するドキュメントを検索します。
語句
Cosmos DB
のテキスト検索を実行します。use cosmicworks db.products.find( { $text: { $search: "Cosmos DB" } } )
必要に応じて、クエリで
$meta
射影演算子とtextScore
フィールドを使用して重みを確認しますuse cosmicworks db.products.find( { $text: { $search: "Cosmos DB" } }, { score: { $meta: "textScore" } } )
制限事項
- コレクションに定義できるテキスト インデックスは 1 つだけです。
- テキスト インデックスではシンプルなテキスト検索をサポートしていますが、正規表現などの高度な検索機能はありません。
- 並べ替え操作では、MongoDB のテキスト インデックスの順序を利用できません。
- Hint() では、$text 式を使用するクエリとの組み合わせはサポートされていません。
- テキスト インデックスは比較的大きくなる可能性があり、他のインデックスの種類と比較して大量の記憶域を消費します。
ワイルドカード インデックス
単一フィールドのインデックス。field
にあるすべてのパスにインデックスを付けます。同じレベルにある他のフィールドは除外されます。 たとえば、次のサンプル ドキュメントの場合
{
"children":
{
"familyName": "Merriam",
"pets": { "details": {“name”: "Goofy", ”age”: 3} }
}
}
{ "pets.$**": 1 } にインデックスを作成すると、詳細プロパティとサブ文書プロパティにインデックスが作成されますが、"familyName" にはインデックスが作成されません。
制限事項
- ワイルドカード インデックスでは、一意のインデックスをサポートできません。
- ワイルドカード インデックスでは、フィルターにワイルドカードに存在するパスのみが含まれていない限り、
ORDER BY
のプッシュダウンはサポートされません (未定義の要素にはインデックスを付けないため)。 - 複合ワイルドカード インデックスには、
one
つのワイルドカード用語とone
つ以上のインデックス用語のみを含めることができます。{ "pets.$**": 1, “familyName”: 1 }
地理空間のインデックス
地理空間インデックスでは、GeoJSON オブジェクトまたは従来の座標ペアとして格納されたデータに対するクエリがサポートされています。 地理空間インデックスを使用すると、地理空間データに対するクエリのパフォーマンスを向上させたり、特定の地理空間クエリを実行したりできます。
Azure Cosmos DB for MongoDB 仮想コアには、次の 2 種類の地理空間インデックスが用意されています。
- 2dsphere インデックス。球体上のジオメトリを解釈するクエリをサポートします。
- 2d インデックス。平面上のジオメトリを解釈するクエリをサポートします。
2d インデックス
2d インデックスは、地理空間データを格納する従来の座標ペア スタイルでのみサポートされます。
createIndex
フィールドに地理空間インデックスを作成するには、2d
メソッドを ___location
オプションと共に使用します。
db.places.createIndex({ "___location": "2d"});
制限事項
one
インデックスに含めることができる位置フィールドは2d
つだけで、他の地理空間ではないフィールドをone
つのみcompound 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})
穴があるポリゴンは機能しません。 穴のあるポリゴンの挿入は制限されませんが、
$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 holes
key
フィールドは、geoNear
を使用するのに必須です。[mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }]) // MongoServerError: $geoNear requires a 'key' option as a String
次のステップ
- 最も効率的な結果を得るためのインデックス作成のベスト プラクティスについて理解する。
- バックグラウンド インデックス作成について理解する
- テキスト インデックス作成の使用について理解する。
- ワイルドカード インデックス作成について理解する。