Azure Cosmos DB でインデックス作成ポリシーを管理する
適用対象: NoSQL
Azure Cosmos DB では、コンテナーごとに定義されたインデックス作成ポリシーに従ってデータのインデックスが作成されます。 新しく作成したコンテナーの既定のインデックス作成ポリシーでは、文字列または数値に範囲インデックスが適用されます。 このポリシーは、独自のカスタム インデックス作成ポリシーでオーバーライドできます。
Note
この記事で説明するインデックス作成ポリシーの更新方法は、Azure Cosmos DB の NoSQL 用 API にのみ適用されます。 「Azure Cosmos DB の MongoDB 用 API」と「Azure Cosmos DB for Apache Cassandra でのセカンダリ インデックス作成」でインデックス作成の詳細について説明します。
インデックス作成ポリシーの例
JSON 形式で示されたインデックス作成ポリシーの例をいくつか紹介します。これは、Azure portal 上に公開される際の方法です。 同じパラメーターは、Azure CLI のほか、任意の SDK で設定することができます。
一部のプロパティ パスを選択的に除外するオプトアウト ポリシー
{
"indexingMode": "consistent",
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/path/to/single/excluded/property/?"
},
{
"path": "/path/to/root/of/multiple/excluded/properties/*"
}
]
}
一部のプロパティ パスを選択的に包含するオプトイン ポリシー
{
"indexingMode": "consistent",
"includedPaths": [
{
"path": "/path/to/included/property/?"
},
{
"path": "/path/to/root/of/multiple/included/properties/*"
}
],
"excludedPaths": [
{
"path": "/*"
}
]
}
Note
一般的に、データ モデルに追加される新しいプロパティのインデックスを Azure Cosmos DB がプロアクティブに作成できるよう、オプトアウト インデックス作成ポリシーの使用をお勧めします。
特定のプロパティ パスに対してのみ空間インデックスを使用する
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/_etag/?"
}
],
"spatialIndexes": [
{
"path": "/path/to/geojson/property/?",
"types": [
"Point",
"Polygon",
"MultiPolygon",
"LineString"
]
}
]
}
複合インデックス作成ポリシーの例
個々のプロパティのパスを含めたり除外したりするほかに、複合インデックスを指定することもできます。 複数のプロパティを対象とする 1 つの ORDER BY
句を使用したクエリを実行したい場合は、これらのプロパティに対する複合インデックスが必要になります。 さらに、複合インデックスには、さまざまなプロパティに複数のフィルターや、1 つのフィルターと 1 つの ORDER BY 句の両方が与えられているクエリでパフォーマンス上の長所があります。
Note
複合パスではスカラー値のインデックスのみが作成されるため、そのパスには /?
が暗黙的に含まれています。 複合パスでは /*
ワイルドカードはサポートされません。 複合パスに /?
または /*
を指定しないでください。
(name asc, age desc) に対して定義された複合インデックス:
{
"automatic":true,
"indexingMode":"Consistent",
"includedPaths":[
{
"path":"/*"
}
],
"excludedPaths":[],
"compositeIndexes":[
[
{
"path":"/name",
"order":"ascending"
},
{
"path":"/age",
"order":"descending"
}
]
]
}
名前と年齢に対する上記の複合インデックスは、クエリ #1 とクエリ #2 で必要になります。
クエリ #1:
SELECT *
FROM c
ORDER BY c.name ASC, c.age DESC
クエリ #2:
SELECT *
FROM c
ORDER BY c.name DESC, c.age ASC
この複合インデックスでは、クエリ #3 とクエリ #4 で長所があり、フィルターが最適化されます。
クエリ #3:
SELECT *
FROM c
WHERE c.name = "Tim"
ORDER BY c.name DESC, c.age ASC
クエリ #4:
SELECT *
FROM c
WHERE c.name = "Tim" AND c.age > 18
(name ASC, age ASC) と (name ASC, age DESC) に定義されている複合インデックス:
同じインデックス作成ポリシー内で、異なる複数の複合インデックスを定義できます。
{
"automatic":true,
"indexingMode":"Consistent",
"includedPaths":[
{
"path":"/*"
}
],
"excludedPaths":[],
"compositeIndexes":[
[
{
"path":"/name",
"order":"ascending"
},
{
"path":"/age",
"order":"ascending"
}
],
[
{
"path":"/name",
"order":"ascending"
},
{
"path":"/age",
"order":"descending"
}
]
]
}
(name ASC, age ASC) に定義されている複合インデックス:
順序の指定は任意です。 指定されていない場合、順序は昇順です。
{
"automatic":true,
"indexingMode":"Consistent",
"includedPaths":[
{
"path":"/*"
}
],
"excludedPaths":[],
"compositeIndexes":[
[
{
"path":"/name",
},
{
"path":"/age",
}
]
]
}
インデックス作成をアクティブ状態に保ちながらすべてのプロパティ パスを除外する
このポリシーは、Time-to-Live (TTL) 機能がアクティブであるものの、(Azure Cosmos DB を純粋なキー/値ストアとして使用するための) 追加のインデックスは不要である状況で使用できます。
{
"indexingMode": "consistent",
"includedPaths": [],
"excludedPaths": [{
"path": "/*"
}]
}
インデックス作成なし
このポリシーによってインデックス作成がオフになります。 indexingMode
が none
に設定されている場合、コンテナーで TTL を設定することはできません。
{
"indexingMode": "none"
}
インデックス作成ポリシーの更新
Azure Cosmos DB では、インデックス作成ポリシーは下のいずれかの方法で更新できます。
- Azure portal を使用する
- Azure CLI を使用する
- PowerShell を使用する
- SDK のいずれかを使用する
インデックス作成ポリシーの更新により、インデックスの変換がトリガーされます。 この変換の進行状況は、SDK から追跡することもできます。
Note
インデックス作成ポリシーを更新するとき、Azure Cosmos DB への書き込みが中断されることはありません。 インデックスの変換について、さらに学習してください
Azure ポータルの使用
Azure Cosmos DB のコンテナーには、そのインデックス作成ポリシーが Azure portal で直接編集できる JSON ドキュメントとして格納されます。
Azure portal にサインインします。
新しい Azure Cosmos DB アカウントを作成するか、既存のアカウントを選択します。
[データ エクスプローラー] ウィンドウを開いて、操作の対象となるコンテナーを選択します。
[Scale & Settings](スケールと設定) をクリックします。
インデックス作成ポリシーの JSON ドキュメントに変更を加えます (以下の例を参照)。
完了したら、 [保存] をクリックします。
Azure CLI の使用
カスタム インデックス作成ポリシーを使用したコンテナーの作成の詳細については、CLI を使用したカスタム インデックス作成ポリシーでのコンテナーの作成に関する説明を参照してください。
PowerShell の使用
カスタム インデックス作成ポリシーを使用したコンテナーの作成の詳細については、PowerShell を使用したカスタム インデックス作成ポリシーでのコンテナーの作成に関する説明を参照してください。
.NET SDK を使用する
.NET SDK v3 の ContainerProperties
オブジェクト (その使用法についてはこちらのクイックスタートを参照) では IndexingPolicy
プロパティを公開しています。これを使用すると、IndexingMode
を変更したり IncludedPaths
や ExcludedPaths
を追加または削除したりすることができます。
// Retrieve the container's details
ContainerResponse containerResponse = await client.GetContainer("database", "container").ReadContainerAsync();
// Set the indexing mode to consistent
containerResponse.Resource.IndexingPolicy.IndexingMode = IndexingMode.Consistent;
// Add an included path
containerResponse.Resource.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
// Add an excluded path
containerResponse.Resource.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/name/*" });
// Add a spatial index
SpatialPath spatialPath = new SpatialPath
{
Path = "/locations/*"
};
spatialPath.SpatialTypes.Add(SpatialType.Point);
containerResponse.Resource.IndexingPolicy.SpatialIndexes.Add(spatialPath);
// Add a composite index
containerResponse.Resource.IndexingPolicy.CompositeIndexes.Add(new Collection<CompositePath> { new CompositePath() { Path = "/name", Order = CompositePathSortOrder.Ascending }, new CompositePath() { Path = "/age", Order = CompositePathSortOrder.Descending } });
// Update container with changes
await client.GetContainer("database", "container").ReplaceContainerAsync(containerResponse.Resource);
インデックス変換の進行状況を追跡するには、PopulateQuotaInfo
プロパティを true
に設定する RequestOptions
オブジェクトを渡したうえで、その値を x-ms-documentdb-collection-index-transformation-progress
応答ヘッダーから取得します。
// retrieve the container's details
ContainerResponse containerResponse = await client.GetContainer("database", "container").ReadContainerAsync(new ContainerRequestOptions { PopulateQuotaInfo = true });
// retrieve the index transformation progress from the result
long indexTransformationProgress = long.Parse(containerResponse.Headers["x-ms-documentdb-collection-index-transformation-progress"]);
新しいコンテナーの作成中にカスタム インデックス作成ポリシーを定義すると、SDK V3 の fluent API によって、この定義を簡潔かつ効率的な方法で記述できます。
await client.GetDatabase("database").DefineContainer(name: "container", partitionKeyPath: "/myPartitionKey")
.WithIndexingPolicy()
.WithIncludedPaths()
.Path("/*")
.Attach()
.WithExcludedPaths()
.Path("/name/*")
.Attach()
.WithSpatialIndex()
.Path("/locations/*", SpatialType.Point)
.Attach()
.WithCompositeIndex()
.Path("/name", CompositePathSortOrder.Ascending)
.Path("/age", CompositePathSortOrder.Descending)
.Attach()
.Attach()
.CreateIfNotExistsAsync();
Java SDK の使用
Java SDK の DocumentCollection
オブジェクト (その使用法についてはこちらのクイック スタートを参照) では、getIndexingPolicy()
および setIndexingPolicy()
メソッドを公開しています。 これらによって操作される IndexingPolicy
オブジェクトを使用すると、インデックス作成モードを変更したり、対象のパスと対象外のパスを追加または削除したりすることができます。
// Retrieve the container's details
Observable<ResourceResponse<DocumentCollection>> containerResponse = client.readCollection(String.format("/dbs/%s/colls/%s", "database", "container"), null);
containerResponse.subscribe(result -> {
DocumentCollection container = result.getResource();
IndexingPolicy indexingPolicy = container.getIndexingPolicy();
// Set the indexing mode to consistent
indexingPolicy.setIndexingMode(IndexingMode.Consistent);
// Add an included path
Collection<IncludedPath> includedPaths = new ArrayList<>();
IncludedPath includedPath = new IncludedPath();
includedPath.setPath("/*");
includedPaths.add(includedPath);
indexingPolicy.setIncludedPaths(includedPaths);
// Add an excluded path
Collection<ExcludedPath> excludedPaths = new ArrayList<>();
ExcludedPath excludedPath = new ExcludedPath();
excludedPath.setPath("/name/*");
excludedPaths.add(excludedPath);
indexingPolicy.setExcludedPaths(excludedPaths);
// Add a spatial index
Collection<SpatialSpec> spatialIndexes = new ArrayList<SpatialSpec>();
Collection<SpatialType> collectionOfSpatialTypes = new ArrayList<SpatialType>();
SpatialSpec spec = new SpatialSpec();
spec.setPath("/locations/*");
collectionOfSpatialTypes.add(SpatialType.Point);
spec.setSpatialTypes(collectionOfSpatialTypes);
spatialIndexes.add(spec);
indexingPolicy.setSpatialIndexes(spatialIndexes);
// Add a composite index
Collection<ArrayList<CompositePath>> compositeIndexes = new ArrayList<>();
ArrayList<CompositePath> compositePaths = new ArrayList<>();
CompositePath nameCompositePath = new CompositePath();
nameCompositePath.setPath("/name");
nameCompositePath.setOrder(CompositePathSortOrder.Ascending);
CompositePath ageCompositePath = new CompositePath();
ageCompositePath.setPath("/age");
ageCompositePath.setOrder(CompositePathSortOrder.Descending);
compositePaths.add(ageCompositePath);
compositePaths.add(nameCompositePath);
compositeIndexes.add(compositePaths);
indexingPolicy.setCompositeIndexes(compositeIndexes);
// Update the container with changes
client.replaceCollection(container, null);
});
コンテナーに対するインデックス変換の進行状況を追跡するには、クォータ情報の読み込みを要求する RequestOptions
オブジェクトを渡したうえで、その値を x-ms-documentdb-collection-index-transformation-progress
応答ヘッダーから取得します。
// set the RequestOptions object
RequestOptions requestOptions = new RequestOptions();
requestOptions.setPopulateQuotaInfo(true);
// retrieve the container's details
Observable<ResourceResponse<DocumentCollection>> containerResponse = client.readCollection(String.format("/dbs/%s/colls/%s", "database", "container"), requestOptions);
containerResponse.subscribe(result -> {
// retrieve the index transformation progress from the response headers
String indexTransformationProgress = result.getResponseHeaders().get("x-ms-documentdb-collection-index-transformation-progress");
});
Node.js SDK の使用
Node.js SDK の ContainerDefinition
インターフェイス (その使用法についてはこちらのクイック スタートを参照) では indexingPolicy
プロパティを公開しています。これを使用すると、indexingMode
を変更したり includedPaths
や excludedPaths
を追加または削除したりすることができます。
コンテナーの詳細を取得する
const containerResponse = await client.database('database').container('container').read();
インデックス作成モードを同期に設定する
containerResponse.body.indexingPolicy.indexingMode = "consistent";
空間インデックスを含む対象パスを追加する
containerResponse.body.indexingPolicy.includedPaths.push({
includedPaths: [
{
path: "/age/*",
indexes: [
{
kind: cosmos.DocumentBase.IndexKind.Range,
dataType: cosmos.DocumentBase.DataType.String
},
{
kind: cosmos.DocumentBase.IndexKind.Range,
dataType: cosmos.DocumentBase.DataType.Number
}
]
},
{
path: "/locations/*",
indexes: [
{
kind: cosmos.DocumentBase.IndexKind.Spatial,
dataType: cosmos.DocumentBase.DataType.Point
}
]
}
]
});
対象外パスを追加する
containerResponse.body.indexingPolicy.excludedPaths.push({ path: '/name/*' });
変更に従ってコンテナーを更新する
const replaceResponse = await client.database('database').container('container').replace(containerResponse.body);
コンテナーに対するインデックス変換の進行状況を追跡するには、populateQuotaInfo
プロパティを true
に設定する RequestOptions
オブジェクトを渡したうえで、その値を x-ms-documentdb-collection-index-transformation-progress
応答ヘッダーから取得します。
// retrieve the container's details
const containerResponse = await client.database('database').container('container').read({
populateQuotaInfo: true
});
// retrieve the index transformation progress from the response headers
const indexTransformationProgress = replaceResponse.headers['x-ms-documentdb-collection-index-transformation-progress'];
Python SDK の使用
Python SDK V3 (その使用法についてはこちらのクイック スタートを参照) を使用する場合、コンテナーの構成がディクショナリとして管理されます。 このディクショナリから、インデックス作成ポリシーとそのすべての属性にアクセスすることができます。
コンテナーの詳細を取得する
containerPath = 'dbs/database/colls/collection'
container = client.ReadContainer(containerPath)
インデックス作成モードを同期に設定する
container['indexingPolicy']['indexingMode'] = 'consistent'
管理対象パスと空間インデックスと共にインデックス作成ポリシーを定義する
container["indexingPolicy"] = {
"indexingMode":"consistent",
"spatialIndexes":[
{"path":"/location/*","types":["Point"]}
],
"includedPaths":[{"path":"/age/*","indexes":[]}],
"excludedPaths":[{"path":"/*"}]
}
非管理対象パスと共にインデックス作成ポリシーを定義する
container["indexingPolicy"] = {
"indexingMode":"consistent",
"includedPaths":[{"path":"/*","indexes":[]}],
"excludedPaths":[{"path":"/name/*"}]
}
複合インデックスを追加する
container['indexingPolicy']['compositeIndexes'] = [
[
{
"path": "/name",
"order": "ascending"
},
{
"path": "/age",
"order": "descending"
}
]
]
変更に従ってコンテナーを更新する
response = client.ReplaceContainer(containerPath, container)
次のステップ
以下の記事で、インデックス作成についての詳細を参照してください。