Documentdb-indexing-records
DocumentDB-レコードのインデックス作成
デフォルトでは、DocumentDBは、ドキュメントがデータベースに追加されるとすぐに、ドキュメント内のすべてのプロパティに自動的にインデックスを付けます。 ただし、インデックスを作成する必要のない特定のドキュメントやプロパティがある場合、ストレージと処理のオーバーヘッドを削減する独自のインデックスポリシーを制御および微調整できます。
すべてのプロパティに自動的にインデックスを付けるようにDocumentDBに指示するデフォルトのインデックスポリシーは、多くの一般的なシナリオに適しています。 ただし、インデックスを作成するものとしないものを正確に制御するカスタムポリシーや、インデックス作成に関するその他の機能を実装することもできます。
DocumentDBは、次の種類のインデックス作成をサポートしています-
- Hash
- 範囲
Hash
ハッシュインデックスを使用すると、等しいかどうかの効率的なクエリが可能になります。つまり、特定のプロパティがより小さい、より大きい、または間の値の範囲で一致するのではなく、正確な値に等しいドキュメントを検索します。
ハッシュインデックスを使用して範囲クエリを実行できますが、DocumentDBは一致するドキュメントを見つけるためにハッシュインデックスを使用できず、代わりに各ドキュメントを順次スキャンして範囲クエリで選択する必要があるかどうかを判断する必要があります。
ハッシュインデックスだけのプロパティでORDER BY句を使用してドキュメントを並べ替えることはできません。
範囲
プロパティに定義された範囲インデックス、DocumentDBにより、値の範囲に対してドキュメントを効率的に照会できます。 また、ORDER BYを使用して、そのプロパティのクエリ結果を並べ替えることができます。
DocumentDBでは、任意またはすべてのプロパティでハッシュと範囲インデックスの両方を定義できます。これにより、効率的な等価クエリと範囲クエリ、およびORDER BYが可能になります。
インデックス作成ポリシー
すべてのコレクションには、すべてのドキュメントのすべてのプロパティの数値と文字列に使用されるインデックスのタイプを指定するインデックスポリシーがあります。
- また、ドキュメントがコレクションに追加されるときに、ドキュメントのインデックスを自動的に作成するかどうかも制御できます。
- 自動インデックスはデフォルトで有効になっていますが、ドキュメントを追加するときにその動作をオーバーライドして、DocumentDBにその特定のドキュメントのインデックスを作成しないように指示できます。
- 自動インデックス作成を無効にして、デフォルトでドキュメントがコレクションに追加されたときにインデックスが作成されないようにすることができます。 同様に、ドキュメントレベルでこれをオーバーライドし、特定のドキュメントをコレクションに追加するときにDocumentDBにインデックスを作成するように指示できます。 これは、手動インデックス付けと呼ばれます。
インデックス作成を含める/除外する
インデックス作成ポリシーでは、インデックスに含めるパスまたは除外するパスを定義することもできます。 これは、クエリを実行しないドキュメントの特定の部分と実行する特定の部分があることがわかっている場合に役立ちます。
これらの場合、コレクションに追加された各ドキュメントの特定の部分のみをインデックス付けするようにDocumentDBに指示することにより、インデックス付けのオーバーヘッドを削減できます。
自動索引付け
自動インデックス作成の簡単な例を見てみましょう。
- ステップ1 *-最初に自動インデックス付けと呼ばれるコレクションを作成し、明示的にポリシーを指定せずに、このコレクションはデフォルトのインデックス付けポリシーを使用します。つまり、このコレクションで自動インデックス付けが有効になります。
ここでは、データベースのセルフリンクにIDベースのルーティングを使用しているため、コレクションを作成する前にリソースIDやクエリを知る必要はありません。 mydbというデータベースIDを使用できます。
- ステップ2 *-次に、姓がUpstonの2つのドキュメントを作成しましょう。
private async static Task AutomaticIndexing(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("*** *Override Automatic Indexing* ***");
//Create collection with automatic indexing
var collectionDefinition = new DocumentCollection {
Id = "autoindexing"
};
var collection = await client.CreateDocumentCollectionAsync("dbs/mydb",
collectionDefinition);
//Add a document (indexed)
dynamic indexedDocumentDefinition = new {
id = "MARK",
firstName = "Mark",
lastName = "Upston",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document indexedDocument = await client
.CreateDocumentAsync("dbs/mydb/colls/autoindexing", indexedDocumentDefinition);
//Add another document (request no indexing)
dynamic unindexedDocumentDefinition = new {
id = "JANE",
firstName = "Jane",
lastName = "Upston",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document unindexedDocument = await client
.CreateDocumentAsync("dbs/mydb/colls/autoindexing", unindexedDocumentDefinition,
new RequestOptions { IndexingDirective = IndexingDirective.Exclude });
//Unindexed document won't get returned when querying on non-ID (or selflink) property
var doeDocs = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing", "SELECT *
FROM c WHERE c.lastName = 'Doe'").ToList();
Console.WriteLine("Documents WHERE lastName = 'Doe': {0}", doeDocs.Count);
//Unindexed document will get returned when using no WHERE clause
var allDocs = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing",
"SELECT *FROM c").ToList();
Console.WriteLine("All documents: {0}", allDocs.Count);
//Unindexed document will get returned when querying by ID (or self-link) property
Document janeDoc = client.CreateDocumentQuery("dbs/mydb/colls/autoindexing",
"SELECT* FROM c WHERE c.id = 'JANE'").AsEnumerable().FirstOrDefault();
Console.WriteLine("Unindexed document self-link: {0}", janeDoc.SelfLink);
//Delete the collection
await client.DeleteDocumentCollectionAsync("dbs/mydb/colls/autoindexing");
}
Mark Upstonのこの最初のものはコレクションに追加され、デフォルトのインデックス付けポリシーに基づいてすぐに自動的にインデックス付けされます。
しかし、Mark Upstonの2番目のドキュメントが追加されると、コレクションのインデックス付けポリシーにかかわらず、DocumentDBにこのドキュメントをインデックス付けしないように明示的に指示するIndexingDirective.Excludeを使用して要求オプションを渡しました。
最後に両方のドキュメントに対して異なるタイプのクエリがあります。
- ステップ3 *-CreateDocumentClientからAutomaticIndexingタスクを呼び出しましょう。
private static async Task CreateDocumentClient() {
//Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await AutomaticIndexing(client);
}
}
上記のコードをコンパイルして実行すると、次の出力が表示されます。
*** *Override Automatic Indexing* ***
Documents WHERE lastName = 'Upston': 1
All documents: 2
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oAOEkfQA=/docs/kV5oAOEkfQACA
AAAAAAAAA==/
ご覧のとおり、このようなドキュメントが2つありますが、Markのインデックスは作成されていないため、クエリはMarkのドキュメントのみを返します。 コレクション内のすべてのドキュメントを取得するWHERE句なしで再度クエリを実行すると、両方のドキュメントの結果セットが取得されます。これは、インデックス付けされていないドキュメントが常にWHERE句のないクエリによって返されるためです。
IDまたはセルフリンクによって、インデックス付けされていないドキュメントを取得することもできます。 したがって、MarkのIDであるMARKでドキュメントを照会すると、DocumentDBがコレクション内でインデックス付けされていなくてもドキュメントを返すことがわかります。
手動インデックス付け
自動インデックス作成を無効にして、手動インデックス作成の簡単な例を見てみましょう。
- ステップ1 *-最初に、手動インデックス作成と呼ばれるコレクションを作成し、自動インデックス作成を明示的に無効にしてデフォルトのポリシーをオーバーライドします。 つまり、別の方法でリクエストしない限り、このコレクションに追加された新しいドキュメントはインデックス付けされません。
private async static Task ManualIndexing(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("*** *Manual Indexing* ***");
//Create collection with manual indexing
var collectionDefinition = new DocumentCollection {
Id = "manualindexing",
IndexingPolicy = new IndexingPolicy {
Automatic = false,
},
};
var collection = await client.CreateDocumentCollectionAsync("dbs/mydb",
collectionDefinition);
//Add a document (unindexed)
dynamic unindexedDocumentDefinition = new {
id = "MARK",
firstName = "Mark",
lastName = "Doe",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document unindexedDocument = await client
.CreateDocumentAsync("dbs/mydb/colls/manualindexing", unindexedDocumentDefinition);
//Add another document (request indexing)
dynamic indexedDocumentDefinition = new {
id = "JANE",
firstName = "Jane",
lastName = "Doe",
addressLine = "123 Main Street",
city = "Brooklyn",
state = "New York",
zip = "11229",
};
Document indexedDocument = await client.CreateDocumentAsync
("dbs/mydb/colls/manualindexing", indexedDocumentDefinition, new RequestOptions {
IndexingDirective = IndexingDirective.Include });
//Unindexed document won't get returned when querying on non-ID (or selflink) property
var doeDocs = client.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
"SELECT *FROM c WHERE c.lastName = 'Doe'").ToList();
Console.WriteLine("Documents WHERE lastName = 'Doe': {0}", doeDocs.Count);
//Unindexed document will get returned when using no WHERE clause
var allDocs = client.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
"SELECT* FROM c").ToList();
Console.WriteLine("All documents: {0}", allDocs.Count);
//Unindexed document will get returned when querying by ID (or self-link) property
Document markDoc = client
.CreateDocumentQuery("dbs/mydb/colls/manualindexing",
"SELECT * FROM c WHERE c.id = 'MARK'")
.AsEnumerable().FirstOrDefault();
Console.WriteLine("Unindexed document self-link: {0}", markDoc.SelfLink);
await client.DeleteDocumentCollectionAsync("dbs/mydb/colls/manualindexing");
}
- ステップ2 *-次に、以前と同じ2つのドキュメントを再度作成します。 コレクションのインデックス作成ポリシーにより、このドキュメントはインデックス化されないため、今回はMarkのドキュメントに特別なリクエストオプションを提供しません。
- ステップ3 *-Markに2番目のドキュメントを追加するとき、RequestOptionsをIndexingDirective.Includeとともに使用して、DocumentDBにこのドキュメントのインデックスを作成するように指示します。
最後に両方のドキュメントに対して異なるタイプのクエリがあります。
- ステップ4 *-CreateDocumentClientからManualIndexingタスクを呼び出しましょう。
private static async Task CreateDocumentClient() {
//Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
await ManualIndexing(client);
}
}
上記のコードをコンパイルして実行すると、次の出力が表示されます。
*** *Manual Indexing* ***
Documents WHERE lastName = 'Upston': 1
All documents: 2
Unindexed document self-link: dbs/kV5oAA==/colls/kV5oANHJPgE=/docs/kV5oANHJPgEBA
AAAAAAAAA==/
繰り返しますが、クエリは2つのドキュメントのうちの1つだけを返しますが、今回はJane Doeを返します。 ただし、以前と同様に、WHERE句なしでクエリを実行すると、Markのインデックス付けされていないドキュメントを含むコレクション内のすべてのドキュメントが取得されます。 また、IDによってインデックスが付けられていないドキュメントを照会することもできます。このIDは、インデックス付けされていなくてもDocumentDBから返されます。