Gerenciar políticas de indexação no Azure Cosmos DB

APLICA-SE A: NoSQL

No Azure Cosmos DB, os dados são indexados seguindo políticas de indexação que são definidas para cada contêiner. A política de indexação padrão para contêineres recém-criados impõe os índices de intervalo para qualquer cadeia de caracteres ou número. Você pode substituir essa política por sua própria política de indexação personalizada.

Observação

O método de atualização das políticas de indexação descritas neste artigo só se aplica ao Azure Cosmos DB for NoSQL. Saiba mais sobre a indexação no Azure Cosmos DB for MongoDB e a indexação secundária no Azure Cosmos DB for Apache Cassandra.

Exemplos de política de indexação

Veja alguns exemplos de políticas de indexação mostradas em seu formato JSON . Eles são expostos no portal do Azure no formato JSON. Os mesmos parâmetros podem ser definidos por meio da CLI do Azure ou qualquer SDK.

Política de recusa para excluir seletivamente alguns caminhos de propriedade

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

Política de aceitação para incluir seletivamente alguns caminhos de propriedade

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

Observação

Geralmente, recomendamos que você utilize uma política de indexação de exclusão. O Azure Cosmos DB indexa proativamente qualquer nova propriedade que possa ser adicionada ao seu modelo de dados.

Como usar um índice espacial em apenas um caminho de propriedade específico

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

Exemplos de política de indexação composta

Além de incluir ou excluir caminhos para as propriedades individuais, você também pode especificar um índice composto. Para executar uma consulta que tenha uma cláusula ORDER BY para várias propriedades, um índice composto é necessário nessas propriedades. Se a consulta incluir filtros junto com a classificação em várias propriedades, talvez seja necessário mais de um índice composto.

Os índices compostos também têm um benefício de desempenho para consultas que têm vários filtros ou um filtro e uma cláusula ORDER BY.

Observação

Os caminhos compostos têm um /? implícito, pois apenas o valor escalar nesse caminho é indexado. Não há suporte para o curinga /* em caminhos compostos. Você não deve especificar /? ou /* em um caminho composto. Os caminhos compostos também diferenciam maiúsculas de minúsculas.

Índice composto definido por (nome crescente, idade decrescente)

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

O índice composto em nome e idade é necessário para as consultas a seguir:

Consulta nº 1:

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

Consulta nº 2:

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

Esse índice composto beneficia as consultas a seguir e otimiza os filtros:

Consulta nº 3:

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

Consulta nº 4:

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

Índice composto definido para (nome ASC, idade ASC) e (nome ASC, idade DESC)

Você pode definir vários índices compostos dentro da mesma política de indexação.

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

Índice composto definido para (nome DESCRESCENTE, idade CRESCENTE)

É opcional especificar o pedido. Se não for especificada, a ordem é crescente.

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

Exclua todos os caminhos de propriedades, mas mantendo a indexação ativa

Você pode usar essa política quando o recurso Vida Útil (TTL) estiver ativo, mas nenhum outro índice for necessário para usar o Azure Cosmos DB como um repositório de valores-chave puro.

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

Nenhuma indexação

Esta política desativa a indexação. Se indexingMode estiver definido como none, você não poderá definir um TTL no contêiner.

{
    "indexingMode": "none"
}

Atualizando a política de indexação

No Azure Cosmos DB, a política de indexação pode ser atualizada usando um dos métodos a seguir:

  • No portal do Azure
  • Usando a CLI do Azure
  • Usando o PowerShell
  • Usando um dos SDKs

Uma atualização de política de indexação dispara uma transformação de índice. O andamento dessa transformação também pode ser acompanhado dos SDKs.

Observação

Quando você atualiza a política de indexação, as gravações no Azure Cosmos DB são ininterruptas. Saiba mais sobre as transformações de indexação

Importante

A remoção de um índice entra em vigor imediatamente, enquanto a adição de um novo índice leva algum tempo, pois requer uma transformação de indexação. Ao substituir um índice por outro (por exemplo, substituindo um único índice de propriedades por um índice composto), adicione o novo índice primeiro e aguarde até que a transformação de índice seja concluída antes de remover o índice anterior da política de indexação. Caso contrário, isso afetará negativamente sua capacidade de consultar o índice anterior e poderá interromper todas as cargas de trabalho ativas que o referenciam.

Usar o portal do Azure

Os contêineres do Azure Cosmos DB armazenam a política de indexação como um documento JSON que o portal do Azure permite a edição direta.

  1. Entre no portal do Azure.

  2. Crie uma conta do Azure Cosmos DB ou selecione uma conta existente.

  3. Abra o painel do Data Explorer e selecione o contêiner no qual deseja trabalhar.

  4. Selecione Escala e Configurações.

  5. Modifique o documento JSON da política de indexação, conforme mostrado nesses exemplos.

  6. Selecione Salvar ao terminar.

Manage Indexing using Azure portal

Usar a CLI do Azure

Para criar um contêiner com uma política de indexação personalizada, confira Criar um contêiner com uma política de índice personalizada usando a CLI.

Usar o PowerShell

Para criar um contêiner com uma política de indexação personalizada, confira Criar um contêiner com uma política de índice personalizada usando o PowerShell.

Usar o SDK .NET

O objeto ContainerProperties do SDK do .NET v3 expõe uma propriedade IndexingPolicy que permite alterar IndexingMode e adicionar ou remover IncludedPaths e ExcludedPaths. Para obter mais informações, confira Início Rápido: biblioteca de cliente do Azure Cosmos DB for NoSQL para.NET.

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

Para acompanhar o progresso de transformação de índice, passe um objeto RequestOptions que define a propriedade PopulateQuotaInfo para true. Recuperar o valor do cabeçalho de resposta 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"]);

A API fluente do SDK V3 permite que você escreva essa definição de maneira concisa e eficiente ao definir uma política de indexação personalizada ao criar um novo contêiner:

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

Usar o SDK do Java

O objeto DocumentCollection do SDK do Java expõe os métodos getIndexingPolicy() e setIndexingPolicy(). O objeto IndexingPolicy que eles manipulam permite que você altere o modo de indexação e adicione ou remova caminhos incluídos ou excluídos. Para obter mais informações, confira Início Rápido: criar um aplicativo Java para gerenciar os dados do Azure Cosmos DB for NoSQL.

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

Para acompanhar o progresso da transformação de índice em um contêiner, passe um objeto RequestOptions que solicita que as informações da cota sejam preenchidas. Recuperar o valor do cabeçalho de resposta 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");
});

Usar o SDK do Node.js

A interface ContainerDefinition do SDK do Node.js expõe uma propriedade indexingPolicy que permite alterar o indexingMode e adicionar ou remover includedPaths e excludedPaths. Para obter mais informações, confira Início Rápido: biblioteca de cliente do Azure Cosmos DB for NoSQL para Node.js.

Recuperar os detalhes do contêiner:

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

Definir o modo de indexação como consistente:

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

Adicione o caminho incluído, incluindo um índice espacial:

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

Adicionar o caminho excluído:

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

Atualizar o contêiner com as alterações:

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

Para acompanhar o progresso da transformação do índice em um contêiner, passe um objeto RequestOptions que define a propriedade populateQuotaInfo como true. Recuperar o valor do cabeçalho de resposta 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'];

Usar o SDK do Python

Quando você usa o SDK V3 do Python, a configuração do contêiner é gerenciada como um dicionário. Nesse dicionário, você pode acessar a política de indexação e todos os seus atributos. Para obter mais informações, confira Início Rápido: biblioteca de cliente do Azure Cosmos DB for NoSQL para Python.

Recuperar os detalhes do contêiner:

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

Definir o modo de indexação como consistente:

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

Definir uma política de indexação com um caminho incluído e um índice espacial:

container["indexingPolicy"] = {

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

Definir uma política de indexação com um caminho excluído:

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

Adicionar um índice composto:

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

Atualizar o contêiner com as alterações:

response = client.ReplaceContainer(containerPath, container)

Próximas etapas

Leia mais sobre indexação nos artigos a seguir: