管理 Azure Cosmos DB 中的索引策略Manage indexing policies in Azure Cosmos DB

在 Azure Cosmos DB 中,数据是按照为每个容器定义的索引策略编制索引的。In Azure Cosmos DB, data is indexed following indexing policies that are defined for each container. 新建容器的默认索引策略会对任何字符串或数字强制使用范围索引。The default indexing policy for newly created containers enforces range indexes for any string or number. 可以使用你自己的自定义索引策略覆盖此策略。This policy can be overridden with your own custom indexing policy.

索引策略示例Indexing policy examples

下面是以 JSON 格式显示的一些索引策略示例,该格式是在 Azure 门户上公开索引策略的方式。Here are some examples of indexing policies shown in their JSON format, which is how they are exposed on the Azure portal. 可以通过 Azure CLI 或任何 SDK 设置相同的参数。The same parameters can be set through the Azure CLI or any SDK.

用以有选择地排除某些属性路径的选择退出策略Opt-out policy to selectively exclude some property paths

    {
        "indexingMode": "consistent",
        "includedPaths": [
            {
                "path": "/*"
            }
        ],
        "excludedPaths": [
            {
                "path": "/path/to/single/excluded/property/?"
            },
            {
                "path": "/path/to/root/of/multiple/excluded/properties/*"
            }
        ]
    }

此索引策略等同于下面的手动将 kinddataTypeprecision 设置为默认值的策略。This indexing policy is equivalent to the one below which manually sets kind, dataType, and precision to their default values. 这些属性不再需要显式设置,可以从索引策略中完全省略它们(如上例所示)。These properties are no longer necessary to explicitly set and you can omit them from your indexing policy entirely (as shown in above example).

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

用以有选择地包括某些属性路径的选择加入策略Opt-in policy to selectively include some property paths

    {
        "indexingMode": "consistent",
        "includedPaths": [
            {
                "path": "/path/to/included/property/?"
            },
            {
                "path": "/path/to/root/of/multiple/included/properties/*"
            }
        ],
        "excludedPaths": [
            {
                "path": "/*"
            }
        ]
    }

此索引策略等同于下面的手动将 kinddataTypeprecision 设置为默认值的策略。This indexing policy is equivalent to the one below which manually sets kind, dataType, and precision to their default values. 这些属性不再需要显式设置,可以从索引策略中完全省略它们(如上例所示)。These properties are no longer necessary to explicitly set and you can omit them from your indexing policy entirely (as shown in above example).

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

备注

通常情况下,建议使用选择退出索引策略来让 Azure Cosmos DB 主动为可能会添加到模型的任何新属性编制索引。It is generally recommended to use an opt-out indexing policy to let Azure Cosmos DB proactively index any new property that may be added to your model.

仅在特定属性路径上使用空间索引Using a spatial index on a specific property path only

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?"
        }
    ],
    "spatialIndexes": [
        {
            "path": "/path/to/geojson/property/?",
            "types": [
                "Point",
                "Polygon",
                "MultiPolygon",
                "LineString"
            ]
        }
    ]
}

组合索引策略示例Composite indexing policy examples

除了包含或排除各属性的路径,还可以指定一个组合索引。In addition to including or excluding paths for individual properties, you can also specify a composite index. 如果要执行具有针对多个属性的 ORDER BY 子句的查询,需要使用这些属性上的组合索引If you would like to perform a query that has an ORDER BY clause for multiple properties, a composite index on those properties is required. 此外,对于具有筛选器且对不同属性使用 ORDER BY 子句的查询,组合索引将具有性能优势。Additionally, composite indexes will have a performance benefit for queries that have a filter and have an ORDER BY clause on different properties.

备注

组合路径具有隐式 /?,因为仅索引该路径上的标量值。Composite paths have an implicit /? since only the scalar value at that path is indexed. 组合路径中不支持使用 /* 通配符。The /* wildcard is not supported in composite paths. 不应在组合路径中指定 /?/*You shouldn't specify /? or /* in a composite path.

针对(name asc、age desc)定义的组合索引:Composite index defined for (name asc, age desc):

    {  
        "automatic":true,
        "indexingMode":"Consistent",
        "includedPaths":[  
            {  
                "path":"/*"
            }
        ],
        "excludedPaths":[],
        "compositeIndexes":[  
            [  
                {  
                    "path":"/name",
                    "order":"ascending"
                },
                {  
                    "path":"/age",
                    "order":"descending"
                }
            ]
        ]
    }

查询 #1 和查询 #2 需要上述对 name 和 age 的组合索引:The above composite index on name and age is required for Query #1 and Query #2:

查询 #1:Query #1:

    SELECT *
    FROM c
    ORDER BY c.name ASC, c.age DESC

查询 #2:Query #2:

    SELECT *
    FROM c
    ORDER BY c.name DESC, c.age ASC

此组合索引将使查询 #3 和查询 #4 受益,并优化筛选器:This composite index will benefit Query #3 and Query #4 and optimize the filters:

查询 #3:Query #3:

SELECT *
FROM c
WHERE c.name = "Tim"
ORDER BY c.name DESC, c.age ASC

查询 #4:Query #4:

SELECT *
FROM c
WHERE c.name = "Tim" AND c.age > 18

为 (name ASC, age ASC) 和 (name ASC, age DESC) 定义的组合索引:Composite index defined for (name ASC, age ASC) and (name ASC, age DESC):

可以在同一个索引策略中定义多个不同的组合索引。You can define multiple different composite indexes within the same indexing policy.

    {  
        "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) 定义的组合索引:Composite index defined for (name ASC, age ASC):

可以选择指定顺序。It is optional to specify the order. 如果未指定,顺序为升序。If not specified, the order is ascending.

{  
        "automatic":true,
        "indexingMode":"Consistent",
        "includedPaths":[  
            {  
                "path":"/*"
            }
        ],
        "excludedPaths":[],
        "compositeIndexes":[  
            [  
                {  
                    "path":"/name",
                },
                {  
                    "path":"/age",
                }
            ]
        ]
}

排除所有属性路径,但使索引保持活动状态Excluding all property paths but keeping indexing active

生存时间 (TTL) 功能处于活动状态但不需要第二索引时(使用 Azure Cosmos DB 作为纯键-值存储),可以使用此策略。This policy can be used in situations where the Time-to-Live (TTL) feature is active but no secondary index is required (to use Azure Cosmos DB as a pure key-value store).

    {
        "indexingMode": "consistent",
        "includedPaths": [],
        "excludedPaths": [{
            "path": "/*"
        }]
    }

无索引No indexing

此策略将关闭索引。This policy will turn off indexing. 如果 indexingMode 设置为 none,则无法在容器上设置 TTL。If indexingMode is set to none, you cannot set a TTL on the container.

    {
        "indexingMode": "none"
    }

更新索引策略Updating indexing policy

在 Azure Cosmos DB 中,可以使用以下任一方法更新索引策略:In Azure Cosmos DB, the indexing policy can be updated using any of the below methods:

  • 从 Azure 门户from the Azure portal
  • 使用 Azure CLIusing the Azure CLI
  • 使用 PowerShellusing PowerShell
  • 使用某个 SDKusing one of the SDKs

索引策略更新会触发索引转换。An indexing policy update triggers an index transformation. 还可以通过 SDK 跟踪此转换的进度。The progress of this transformation can also be tracked from the SDKs.

备注

更新索引策略时,对 Azure Cosmos DB 的写入不会中断。When updating indexing policy, writes to Azure Cosmos DB will be uninterrupted. 在重新编制索引期间,查询可能会在更新索引时返回部分结果。During re-indexing, queries may return partial results as the index is being updated.

使用 Azure 门户Use the Azure portal

Azure Cosmos 容器将其索引策略存储为 JSON 文档,可以在 Azure 门户中直接编辑这些文档。Azure Cosmos containers store their indexing policy as a JSON document that the Azure portal lets you directly edit.

  1. 登录到 Azure 门户Sign in to the Azure portal.

  2. 创建新的 Azure Cosmos 帐户或选择现有的帐户。Create a new Azure Cosmos account or select an existing account.

  3. 打开“数据资源管理器”窗格,选择要使用的容器。Open the Data Explorer pane and select the container that you want to work on.

  4. 单击“缩放设置”。Click on Scale & Settings.

  5. 修改索引策略 JSON 文档(请参阅下文中的示例)Modify the indexing policy JSON document (see examples below)

  6. 完成后,单击“保存”。Click Save when you are done.

    使用 Azure 门户管理索引编制

使用 Azure CLIUse the Azure CLI

若要创建具有自定义索引策略的容器,请参阅使用 CLI 创建具有自定义索引策略的容器To create a container with a custom indexing policy see, Create a container with a custom index policy using CLI

使用 PowerShellUse PowerShell

若要创建具有自定义索引策略的容器,请参阅使用 Powershell 创建具有自定义索引策略的容器To create a container with a custom indexing policy see, Create a container with a custom index policy using Powershell

使用 .NET SDKUse the .NET SDK

.NET SDK v2 中的 DocumentCollection 对象公开了一个 IndexingPolicy 属性,可以通过该属性更改 IndexingMode 以及添加或删除 IncludedPathsExcludedPathsThe DocumentCollection object from the .NET SDK v2 exposes an IndexingPolicy property that lets you change the IndexingMode and add or remove IncludedPaths and ExcludedPaths.

// 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);

若要跟踪索引转换进度,请传递一个 RequestOptions 对象,用以将 PopulateQuotaInfo 属性设置为 trueTo track the index transformation progress, pass a RequestOptions object that sets the PopulateQuotaInfo property to true.

// 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 SDKUse the Java SDK

Java SDK 中的 DocumentCollection 对象(请参阅有关其用法的此快速入门)公开了 getIndexingPolicy()setIndexingPolicy() 方法。The DocumentCollection object from the Java SDK (see this Quickstart regarding its usage) exposes getIndexingPolicy() and setIndexingPolicy() methods. 通过它们操作的 IndexingPolicy 对象,你可以更改索引模式,以及添加或删除包括的和排除的路径。The IndexingPolicy object they manipulate lets you change the indexing mode and add or remove included and excluded paths.

// 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 响应标头中检索该值。To track the index transformation progress on a container, pass a RequestOptions object that requests the quota info to be populated, then retrieve the value from the x-ms-documentdb-collection-index-transformation-progress response header.

// 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 SDKUse the Node.js SDK

Node.js SDK 中的 ContainerDefinition 接口(请参阅有关其用法的此快速入门)公开了一个 indexingPolicy 属性,可以通过该属性更改 indexingMode 以及添加或删除 includedPathsexcludedPathsThe ContainerDefinition interface from Node.js SDK (see this Quickstart regarding its usage) exposes an indexingPolicy property that lets you change the indexingMode and add or remove includedPaths and excludedPaths.

检索容器的详细信息Retrieve the container's details

const containerResponse = await client.database('database').container('container').read();

将索引模式设置为“一致”Set the indexing mode to consistent

containerResponse.body.indexingPolicy.indexingMode = "consistent";

添加包含的路径(包括空间索引)Add included path including a spatial index

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
          }
        ]
      }
    ]
  });

添加排除的路径Add excluded path

containerResponse.body.indexingPolicy.excludedPaths.push({ path: '/name/*' });

使用更改更新容器Update the container with changes

const replaceResponse = await client.database('database').container('container').replace(containerResponse.body);

若要在容器上跟踪索引转换进度,请传递一个用以将 populateQuotaInfo 属性设置为 trueRequestOptions 对象,然后从 x-ms-documentdb-collection-index-transformation-progress 响应标头中检索该值。To track the index transformation progress on a container, pass a RequestOptions object that sets the populateQuotaInfo property to true, then retrieve the value from the x-ms-documentdb-collection-index-transformation-progress response header.

// 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 SDKUse the Python SDK

使用 Python SDK V3 时(有关其用法,请参阅此快速入门),容器配置将作为字典进行管理。When using the Python SDK V3 (see this Quickstart regarding its usage), the container configuration is managed as a dictionary. 从此字典中,可以访问索引策略及其所有属性。From this dictionary, it is possible to access the indexing policy and all its attributes.

检索容器的详细信息Retrieve the container's details

containerPath = 'dbs/database/colls/collection'
container = client.ReadContainer(containerPath)

将索引模式设置为“一致”Set the indexing mode to consistent

container['indexingPolicy']['indexingMode'] = 'consistent'

使用包含的路径和空间索引定义索引策略Define an indexing policy with an included path and a spatial index

container["indexingPolicy"] = {

    "indexingMode":"consistent",
    "spatialIndexes":[
                {"path":"/location/*","types":["Point"]}
             ],
    "includedPaths":[{"path":"/age/*","indexes":[]}],
    "excludedPaths":[{"path":"/*"}]
}

使用排除的路径定义索引策略Define an indexing policy with an excluded path

container["indexingPolicy"] = {
    "indexingMode":"consistent",
    "includedPaths":[{"path":"/*","indexes":[]}],
    "excludedPaths":[{"path":"/name/*"}]
}

添加组合索引Add a composite index

container['indexingPolicy']['compositeIndexes'] = [
                [
                    {
                        "path": "/name",
                        "order": "ascending"
                    },
                    {
                        "path": "/age",
                        "order": "descending"
                    }
                ]
                ]

使用更改更新容器Update the container with changes

response = client.ReplaceContainer(containerPath, container)

后续步骤Next steps

阅读以下文章中有关索引的详细信息:Read more about the indexing in the following articles: