Azure Cosmos DB でインデックス作成ポリシーを管理する

適用対象: SQL API

Azure Cosmos DB では、コンテナーごとに定義されたインデックス作成ポリシーに従ってデータのインデックスが作成されます。 新しく作成したコンテナーの既定のインデックス作成ポリシーでは、文字列または数値に範囲インデックスが適用されます。 このポリシーは、独自のカスタム インデックス作成ポリシーでオーバーライドできます。

Note

この記事で説明するインデックス作成ポリシーの更新方法は、Azure Cosmos DB の SQL (Core) API にのみ適用されます。 「Azure Cosmos DB の MongoDB 用 API」と「Azure Cosmos DB Cassandra API でのセカンダリ インデックス作成」でインデックス作成の詳細について説明します。

インデックス作成ポリシーの例

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/*"
            }
        ]
    }

このインデックス作成ポリシーは、kinddataTypeprecision を既定値に手動で設定する下のポリシーと同じです。 これらのプロパティは明示的に設定する必要がなく、インデックス作成ポリシーから完全に除外する必要があります (上記の例を参照)。 これらのプロパティを設定しようとすると、インデックス作成ポリシーから自動的に削除されます。

    {
        "indexingMode": "consistent",
        "includedPaths": [
            {
                "path": "/*",
                "indexes": [
                    {
                        "kind": "Range",
                        "dataType": "Number",
                        "precision": -1
                    },
                    {
                        "kind": "Range",
                        "dataType": "String",
                        "precision": -1
                    }
                ]
            }
        ],
        "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": "/*"
            }
        ]
    }

このインデックス作成ポリシーは、kinddataTypeprecision を既定値に手動で設定する下のポリシーと同じです。 これらのプロパティは明示的に設定する必要がなく、インデックス作成ポリシーから完全に除外する必要があります (上記の例を参照)。 これらのプロパティを設定しようとすると、インデックス作成ポリシーから自動的に削除されます。

    {
        "indexingMode": "consistent",
        "includedPaths": [
            {
                "path": "/path/to/included/property/?",
                "indexes": [
                    {
                        "kind": "Range",
                        "dataType": "Number"
                    },
                    {
                        "kind": "Range",
                        "dataType": "String"
                    }
                ]
            },
            {
                "path": "/path/to/root/of/multiple/included/properties/*",
                "indexes": [
                    {
                        "kind": "Range",
                        "dataType": "Number"
                    },
                    {
                        "kind": "Range",
                        "dataType": "String"
                    }
                ]
            }
        ],
        "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": "/*"
        }]
    }

インデックス作成なし

このポリシーによってインデックス作成がオフになります。 indexingModenone に設定されている場合、コンテナーで TTL を設定することはできません。

    {
        "indexingMode": "none"
    }

インデックス作成ポリシーの更新

Azure Cosmos DB では、インデックス作成ポリシーは下のいずれかの方法で更新できます。

  • Azure portal を使用する
  • Azure CLI を使用する
  • PowerShell を使用する
  • SDK のいずれかを使用する

インデックス作成ポリシーの更新により、インデックスの変換がトリガーされます。 この変換の進行状況は、SDK から追跡することもできます。

Note

インデックス作成ポリシーを更新するとき、Azure Cosmos DB への書き込みが中断されることはありません。 インデックスの変換について、さらに学習してください

Azure ポータルの使用

Azure Cosmos のコンテナーには、そのインデックス作成ポリシーが Azure portal で直接編集できる JSON ドキュメントとして格納されます。

  1. Azure portal にサインインします。

  2. 新しい Azure Cosmos アカウントを作成するか、既存のアカウントを選択します。

  3. [データ エクスプローラー] ウィンドウを開いて、操作の対象となるコンテナーを選択します。

  4. [Scale & Settings](スケールと設定) をクリックします。

  5. インデックス作成ポリシーの JSON ドキュメントに変更を加えます (以下の例を参照)。

  6. 完了したら、 [保存] をクリックします。

Manage Indexing using Azure portal

Azure CLI の使用

カスタム インデックス作成ポリシーを使用したコンテナーの作成の詳細については、CLI を使用したカスタム インデックス作成ポリシーでのコンテナーの作成に関する説明を参照してください。

PowerShell の使用

カスタム インデックス作成ポリシーを使用したコンテナーの作成の詳細については、PowerShell を使用したカスタム インデックス作成ポリシーでのコンテナーの作成に関する説明を参照してください。

.NET SDK を使用する

.NetSDK v2DocumentCollection オブジェクトでは、IndexingMode を変更し、IncludedPaths および ExcludedPaths を追加または削除できる IndexingPolicy プロパティを公開しています。

// Retrieve the container's details
ResourceResponse<DocumentCollection> containerResponse = await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri("database", "container"));
// 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
containerResponse.Resource.IndexingPolicy.SpatialIndexes.Add(new SpatialSpec() { Path = "/locations/*", SpatialTypes = new Collection<SpatialType>() { SpatialType.Point } } );
// 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.ReplaceDocumentCollectionAsync(containerResponse.Resource);

インデックス変換の進行状況を追跡するには、PopulateQuotaInfo プロパティを true に設定する RequestOptions オブジェクトを渡します。

// retrieve the container's details
ResourceResponse<DocumentCollection> container = await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri("database", "container"), new RequestOptions { PopulateQuotaInfo = true });
// retrieve the index transformation progress from the result
long indexTransformationProgress = container.IndexTransformationProgress;

Java SDK の使用

Java SDKDocumentCollection オブジェクト (その使用法についてはこちらのクイック スタートを参照) では、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 SDKContainerDefinition インターフェイス (その使用法についてはこちらのクイック スタートを参照) では indexingPolicy プロパティを公開しています。これを使用すると、indexingMode を変更したり includedPathsexcludedPaths を追加または削除したりすることができます。

コンテナーの詳細を取得する

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)

次のステップ

以下の記事で、インデックス作成についての詳細を参照してください。