Partilhar via


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

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 vetorial

Além de incluir ou excluir caminhos para propriedades individuais, você também pode especificar um índice de vetor. Em geral, os índices vetoriais devem ser especificados sempre que a função do VectorDistance sistema é usada para medir a semelhança entre um vetor de consulta e uma propriedade vetorial.

Nota

Antes de continuar, você deve habilitar a Indexação e Pesquisa de Vetores NoSQL do Azure Cosmos DB.

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 inserção. Não adicionar o caminho do vetor a "excludedPaths" resultará em maior carga de RU e latência para inserções vetoriais.

Importante

Atualmente, as políticas vetoriais e os índices vetoriais 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 vetorial:

Tipo Description Dimensões máximas
flat Armazena vetores no mesmo índice que outras propriedades indexadas. 505
quantizedFlat Quantifica (comprime) vetores antes de armazenar no índice. Isso 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 no DiskANN para uma pesquisa aproximada rápida e eficiente. 4096

Os flat tipos e quantizedFlat índice aproveitam o índice do Azure Cosmos DB para armazenar e ler cada vetor ao executar uma pesquisa vetorial. As pesquisas vetoriais com um flat índice 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 plano.

O quantizedFlat índice armazena vetores quantizados ou compactados no índice. Pesquisas vetoriais com quantizedFlat índice também são pesquisas de força bruta, no entanto, sua precisão pode ser um pouco inferior a 100%, uma vez que os vetores são quantificados antes de adicionar ao índice. No entanto, as pesquisas vetoriais com quantized flat devem ter menor latência, maior taxa de transferência e menor custo de RU do que as pesquisas vetoriais em um flat índice. Esta é uma boa opção para cenários em que você está usando filtros de consulta para restringir a pesquisa vetorial a um conjunto relativamente pequeno de vetores.

O diskANN índice é um índice separado definido especificamente para vetores que utilizam o DiskANN, um conjunto de algoritmos de indexação vetorial de alto desempenho desenvolvidos pela Microsoft Research. Os índices DiskANN podem oferecer algumas das consultas de menor latência, maior consulta por segundo (QPS) e menor custo de RU com alta precisão. No entanto, como o DiskANN é um índice de vizinhos mais próximos aproximados (ANN), a precisão pode ser menor do que quantizedFlat ou flat.

Os diskANN índices e quantizedFlat podem usar parâmetros opcionais de compilação de índice que podem ser usados para ajustar a troca de precisão vs latência que se aplica a cada índice vetorial Vizinhos Aproximados Mais Próximos.

  • quantizationByteSize: Define o tamanho (em bytes) para a quantização do produto. Min=1, Default=dynamic (o sistema decide), Max=512. Definir isso maior pode resultar em pesquisas vetoriais de maior precisão às custas de maior custo de RU e maior latência. Isso se aplica a ambos os quantizedFlat tipos e índice DiskANN .
  • indexingSearchListSize: Define quantos vetores pesquisar durante a construção da construção do índice. Mín=10, Padrão=100, Máx=500. Definir isso maior pode resultar em pesquisas vetoriais de maior precisão às custas de tempos de compilação de índice mais longos e latências de ingestão de vetores mais altas. Isto aplica-se apenas aos DiskANN índices.

Exemplos de política de indexação Tuple

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 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 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 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.

Gerenciar indexação usando o portal do Azure

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 do Node.js

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

Adicione 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;

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)