Gerenciar políticas de indexação no Azure Cosmos DB
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 de vetor
Além de incluir ou excluir caminhos para propriedades individuais, você também pode especificar um índice de vetor. Em geral, os índices de vetor devem ser especificados sempre que a função do sistema VectorDistance
é usada para medir a similaridade entre um vetor de consulta e uma propriedade de vetor.
Observação
Antes de continuar, você deve habilitar a Indexação e Busca e indexação em Vetores do Azure Cosmos DB for NoSQL.
Importante
Uma política de indexação de vetores deve estar no mesmo caminho definido na política de vetores do contêiner. Saiba mais sobre as políticas de vetor de contêiner.
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/_etag/?"
},
{
"path": "/vector/*"
}
],
"vectorIndexes": [
{
"path": "/vector",
"type": "quantizedFlat"
}
]
}
Importante
O caminho do vetor adicionado à seção "excludedPaths" da política de indexação para garantir um desempenho otimizado para a inserção. Não adicionar o caminho do vetor a "excludedPaths" resultará em maior cobrança de RU e latência para inserções de vetores.
Importante
Atualmente, as políticas de vetor e os índices de vetor são imutáveis após a criação. Para fazer alterações, crie uma nova coleção.
Você pode definir os seguintes tipos de políticas de índice de vetor:
Tipo | Descrição | Dimensões máximas |
---|---|---|
flat |
Armazena vetores no mesmo índice que outras propriedades indexadas. | 505 |
quantizedFlat |
Quantifica (compacta) vetores antes de armazenar no índice. Isto pode melhorar a latência e a taxa de transferência ao custo de uma pequena quantidade de precisão. | 4096 |
diskANN |
Cria um índice baseado em DiskANN para uma pesquisa aproximada rápida e eficiente. | 4096 |
Os tipos de índice flat
e quantizedFlat
aproveitam o índice do Azure Cosmos DB para armazenar e ler cada vetor ao executar uma busca em vetores. Buscas em vetores com um índice flat
são pesquisas de força bruta e produzem 100% de precisão. No entanto, há uma limitação de 505
dimensões para vetores em um índice simples.
O índice quantizedFlat
armazena vetores quantificados ou compactados no índice. Buscas em vetores com índice quantizedFlat
também são pesquisas de força bruta; no entanto, sua precisão pode ser ligeiramente menor que 100%, uma vez que os vetores são quantificados antes de adicionar ao índice. No entanto, buscas em vetores com quantized flat
devem ter menor latência, maior taxa de transferência e menor custo de RU do que buscas em vetores em um índice flat
. Esta é uma boa opção para cenários em que você está usando filtros de consulta para restringir a busca em vetores a um conjunto relativamente pequeno de vetores.
O índice diskANN
é um índice separado definido especificamente para vetores que aproveitam o DiskANN, um conjunto de algoritmos de indexação de vetores de alto desempenho desenvolvidos pelo Microsoft Research. Os índices DiskANN podem oferecer algumas das menores latências, consultas por segundo (QPS) mais altas e consultas de custo de RU mais baixas com alta precisão. No entanto, como o DiskANN é um índice aproximado de vizinhos mais próximos (ANN), a precisão pode ser menor que quantizedFlat
ou flat
.
Os índices diskANN
e quantizedFlat
podem usar parâmetros opcionais de build de índice que podem ser usados para ajustar a precisão versus a troca de latência que se aplica a todos os índices de vetor Vizinhos Mais Próximos Aproximados.
quantizationByteSize
: define o tamanho (em bytes) para a quantização do produto. Min=1, Default=dynamic (system decides), Max=512. Definir esse valor maior pode resultar em busca em vetores de maior precisão em detrimento de maior custo de RU e latência mais alta. Isso se aplica aos tipos de índicequantizedFlat
eDiskANN
.indexingSearchListSize
: define quantos vetores pesquisar durante a construção da compilação do índice. Min=10, Default=100, Max=500. Definir esse valor maior pode resultar em busca em vetores de maior precisão em detrimento de tempos de build de índice mais longos e latências de ingestão de vetor mais altas. Isso se aplica somente a índicesDiskANN
.
Exemplos de política de indexação de tupla
Este exemplo de política de indexação define um índice de tupla em events.name e events.category
{
"automatic":true,
"indexingMode":"Consistent",
"includedPaths":[
{"path":"/*"},
{"path":"/events/[]/{name,category}/?"}
],
"excludedPaths":[],
"compositeIndexes":[]
}
O índice acima é usado para a consulta abaixo.
SELECT *
FROM root r
WHERE
EXISTS (SELECT VALUE 1 FROM ev IN r.events
WHERE ev.name = ‘M&M’ AND ev.category = ‘Candy’)
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.
Entre no portal do Azure.
Crie uma conta do Azure Cosmos DB ou selecione uma conta existente.
Abra o painel do Data Explorer e selecione o contêiner no qual deseja trabalhar.
Selecione Escala e Configurações.
Modifique o documento JSON da política de indexação, conforme mostrado nesses exemplos.
Selecione Salvar ao terminar.
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'];
Adicionar um índice composto:
console.log("create container with composite indexes");
const containerDefWithCompositeIndexes = {
id: "containerWithCompositeIndexingPolicy",
indexingPolicy: {
automatic: true,
indexingMode: IndexingMode.consistent,
includedPaths: [
{
path: "/*",
},
],
excludedPaths: [
{
path: '/"systemMetadata"/*',
},
],
compositeIndexes: [
[
{ path: "/field", order: "ascending" },
{ path: "/key", order: "ascending" },
],
],
},
};
const containerWithCompositeIndexes = (
await database.containers.create(containerDefWithCompositeIndexes)
).container;
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)