Gerir 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 definidas para cada contêiner. A política de indexação predefinida para os contentores recém-criados impõe índices de intervalo para qualquer cadeia ou número. Você pode substituir essa política por sua própria política de indexação personalizada.

Nota

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

Exemplos de política de indexação

Aqui estão 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 de qualquer SDK.

Política de exclusão 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": "/*"
        }
    ]
}

Nota

Geralmente, recomendamos que você use 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.

Usando um índice espacial somente em 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 propriedades individuais, você também pode especificar um índice composto. Para executar uma consulta que tenha uma ORDER BY cláusula para várias propriedades, é necessário um índice composto nessas propriedades. Se a consulta incluir filtros juntamente com a classificação em várias propriedades, talvez você precise de 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.

Nota

Os caminhos compostos têm um implícito /? , uma vez que apenas o valor escalar nesse caminho é indexado. O curinga /* não é suportado 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 para (nome asc, idade desc)

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

O índice composto sobre nome e idade é necessário para as seguintes consultas:

Consulta #1:

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

Consulta #2:

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

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

Consulta #3:

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

Consulta #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 ASC, idade ASC)

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

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

Excluir todos os caminhos de propriedade, mas manter a indexação ativa

Você pode usar essa política onde o recurso TTL (Time-to-Live) está ativo, mas nenhum outro índice é necessário para usar o Azure Cosmos DB como um armazenamento de chave-valor puro.

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

Sem indexação

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

{
    "indexingMode": "none"
}

Atualização da política de indexação

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

  • No portal do Azure
  • Com a CLI do Azure
  • Através do PowerShell
  • Usando um dos SDKs

Uma atualização da política de indexação aciona uma transformação de índice. O progresso dessa transformação também pode ser acompanhado a partir dos SDKs.

Nota

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

Importante

A remoção de um índice afeta 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 propriedade por um índice composto), certifique-se de adicionar o novo índice primeiro e, em seguida, aguarde a conclusão da transformação do índice 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 quaisquer cargas de trabalho ativas que façam referência ao índice anterior.

Utilizar o portal do Azure

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

  1. Inicie sessão no portal do Azure.

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

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

  4. Selecione Dimensionar & Configurações.

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

  6. Quando terminar, selecione Guardar.

Manage Indexing using Azure portal

Utilizar a CLI do Azure

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

Utilizar o PowerShell

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

Utilizar o .NET SDK

O ContainerProperties objeto do SDK do .NET v3 expõe uma IndexingPolicy propriedade que permite alterar o IndexingMode e adicionar ou remover IncludedPaths e ExcludedPaths. Para obter mais informações, consulte Guia de início rápido: biblioteca de cliente do Azure Cosmos DB para 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 da transformação do índice, passe um RequestOptions objeto que defina a PopulateQuotaInfo propriedade como true. Recupere o x-ms-documentdb-collection-index-transformation-progress valor do cabeçalho de resposta.

// 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 forma 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 Java SDK

O DocumentCollection objeto do Java SDK expõe os getIndexingPolicy() métodos e setIndexingPolicy() . O IndexingPolicy objeto que eles manipulam permite alterar o modo de indexação e adicionar ou remover caminhos incluídos e excluídos. Para obter mais informações, consulte Guia de início rápido: criar um aplicativo Java para gerenciar dados do Azure Cosmos DB para 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 do índice em um contêiner, passe um RequestOptions objeto que solicita que as informações da cota sejam preenchidas. Recupere o x-ms-documentdb-collection-index-transformation-progress valor do cabeçalho de resposta.

// 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 .js nó

A ContainerDefinition interface do Node.js SDK expõe uma indexingPolicy propriedade que permite alterar o indexingMode e adicionar ou remover includedPaths e excludedPaths. Para obter mais informações, consulte Guia de início rápido - Biblioteca de cliente do Azure Cosmos DB para NoSQL para Node.js.

Recupere os detalhes do contêiner:

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

Defina 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 caminho excluído:

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

Atualize o contêiner com 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 RequestOptions objeto que defina a populateQuotaInfo propriedade como true. Recupere o x-ms-documentdb-collection-index-transformation-progress valor do cabeçalho de resposta.

// 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'];

Utilizar o SDK Python

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

Recupere os detalhes do contêiner:

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

Defina o modo de indexação como consistente:

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

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

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

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

Adicione um índice composto:

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

Atualize o contêiner com alterações:

response = client.ReplaceContainer(containerPath, container)

Próximos passos

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