Vetores de índice e consulta no Azure Cosmos DB for NoSQL em Java

APLICA-SE A: NoSQL

A busca em vetores no Azure Cosmos DB for NoSQL é atualmente uma versão prévia do recurso. Você é obrigado a se registrar para a visualização antes de usar. Este artigo aborda as seguintes etapas:

  1. Registrando-se para a versão prévia do busca em vetores no Azure Cosmos DB for NoSQL
  2. Configurando o contêiner do Azure Cosmos DB para busca em vetores
  3. Criação de política de incorporação de vetores
  4. Adicionando índices vetoriais à política de indexação de contêiner
  5. Criando um contêiner com índices vetoriais e política de incorporação de vetores
  6. Realizando uma busca em vetores nos dados armazenados.
  7. Esse guia percorre o processo de criação de dados vetoriais, indexação dos dados e consulta dos dados em um contêiner.

Pré-requisitos

Registrando-se para a visualização

A busca em vetores do Azure Cosmos DB for NoSQL requer o registo de versão prévia do recurso. Siga as etapas abaixo para se registrar:

  1. Navegue até a página de recursos do Azure Cosmos DB for NoSQL.

  2. Selecione o painel "Recursos" no item de menu "Configurações".

  3. Selecione "Busca em Vetores no Azure Cosmos DB for NoSQL".

  4. Leia a descrição do recurso para confirmar que deseja se inscrever na versão prévia.

  5. Selecione "Ativar" para se inscrever na versão prévia.

Observação

A solicitação de registro será aprovada automaticamente, porém pode levar alguns minutos para entrar em vigor.

As etapas a seguir pressupõem que você saiba como configurar uma conta NoSQL do Cosmos DB e criar um banco de dados. Atualmente, o recurso de busca em vetores não é compatível com os contêineres existentes, portanto, é necessário criar um novo contêiner e especificar a política de incorporação de vetores no nível do contêiner e a política de indexação de vetores no momento da criação do contêiner.

Vejamos um exemplo de criação de um banco de dados para uma livraria baseada na Internet e você armazena Título, Autor, ISBN e Descrição para cada livro. Também definimos duas propriedades para conter incorporações de vetores. A primeira é a propriedade “contentVector”, que contém embeddings de texto gerados a partir do conteúdo de texto do livro (por exemplo, concatenando as propriedades “title” “author” “isbn” e “description” antes de criar o embedding). O segundo é o “coverImageVector”, que é gerado a partir de imagens da capa do livro.

  1. Crie e armazene incorporações de vetores para os campos nos quais deseja realizar a busca em vetores.
  2. Especifique os caminhos de incorporação de vetores na política de incorporação de vetores.
  3. Inclua quaisquer índices vetoriais desejados na política de indexação do contêiner.

Nas seções subsequentes deste artigo, consideraremos a estrutura abaixo para os itens armazenados em nosso contêiner:

{
"title": "book-title", 
"author": "book-author", 
"isbn": "book-isbn", 
"description": "book-description", 
"contentVector": [2, -1, 4, 3, 5, -2, 5, -7, 3, 1], 
"coverImageVector": [0.33, -0.52, 0.45, -0.67, 0.89, -0.34, 0.86, -0.78] 
} 

Criar o objeto com o CosmosContainerProperties.

CosmosContainerProperties collectionDefinition = new CosmosContainerProperties(UUID.randomUUID().toString(), "Partition_Key_Def");

Criando uma política de incorporação de vetores para seu contêiner.

Em seguida, você precisa definir uma política de vetor de contêiner. Essa política fornece informações que são usadas para informar ao mecanismo de consulta do Azure Cosmos DB como lidar com propriedades vetoriais nas funções do sistema VectorDistance. Isso também informa a política de indexação de vetores sobre as informações necessárias, caso você opte por especificar uma. As seguintes informações estão incluídas na política de vetores contidos:

  • “caminho”: o caminho da propriedade que contém vetores
  • “datatype”: O tipo dos elementos do vetor (padrão Float32)
  • “dimensões”: O comprimento de cada vetor no caminho (padrão 1536)
  • “distanceFunction”: A métrica usada para calcular distância/semelhança (cosseno padrão)

Para nosso exemplo com detalhes do livro, a política vetorial pode ser semelhante ao exemplo JSON:

// Creating vector embedding policy
CosmosVectorEmbeddingPolicy cosmosVectorEmbeddingPolicy = new CosmosVectorEmbeddingPolicy();

CosmosVectorEmbedding embedding1 = new CosmosVectorEmbedding();
embedding1.setPath("/coverImageVector");
embedding1.setDataType(CosmosVectorDataType.FLOAT32);
embedding1.setDimensions(8L);
embedding1.setDistanceFunction(CosmosVectorDistanceFunction.COSINE);

CosmosVectorEmbedding embedding2 = new CosmosVectorEmbedding();
embedding2.setPath("/contentVector");
embedding2.setDataType(CosmosVectorDataType.FLOAT32);
embedding2.setDimensions(10L);
embedding2.setDistanceFunction(CosmosVectorDistanceFunction.DOT_PRODUCT);

cosmosVectorEmbeddingPolicy.setCosmosVectorEmbeddings(Arrays.asList(embedding1, embedding2, embedding3));

collectionDefinition.setVectorEmbeddingPolicy(cosmosVectorEmbeddingPolicy);

Criando um índice vetorial na política de indexação

Uma vez decididos os caminhos de incorporação do vetor, os índices vetoriais precisam ser adicionados à política de indexação. Atualmente, a funcionalidade de busca em vetores do Azure Cosmos DB for NoSQL tem suporte apenas em novos contêiner, pelo que é necessário aplicar a política de vetores durante o momento da criação do contentor e essa não pode ser modificada posteriormente. Para esse exemplo, a política de indexação seria semelhante a abaixo:

IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);
ExcludedPath excludedPath1 = new ExcludedPath("/coverImageVector/*");
ExcludedPath excludedPath2 = new ExcludedPath("/contentVector/*");
indexingPolicy.setExcludedPaths(ImmutableList.of(excludedPath1, excludedPath2));

IncludedPath includedPath1 = new IncludedPath("/*");
indexingPolicy.setIncludedPaths(Collections.singletonList(includedPath1));

// Creating vector indexes
CosmosVectorIndexSpec cosmosVectorIndexSpec1 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec1.setPath("/coverImageVector");
cosmosVectorIndexSpec1.setType(CosmosVectorIndexType.QUANTIZED_FLAT.toString());

CosmosVectorIndexSpec cosmosVectorIndexSpec2 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec2.setPath("/contentVector");
cosmosVectorIndexSpec2.setType(CosmosVectorIndexType.DISK_ANN.toString());

indexingPolicy.setVectorIndexes(Arrays.asList(cosmosVectorIndexSpec1, cosmosVectorIndexSpec2, cosmosVectorIndexSpec3));

collectionDefinition.setIndexingPolicy(indexingPolicy);

Por fim, crie o contêiner com a política de índice de contêiner e a política de índice vetorial.

database.createContainer(collectionDefinition).block();

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, a busca em vetores no Azure Cosmos DB for NoSQL só tem suporte em novos contêineres. Você precisa definir a política de vetor de contêiner e qualquer política de indexação de vetor durante o momento da criação do contêiner, pois ela não pode ser modificada posteriormente. Ambas as políticas poderão ser modificadas em uma melhoria futura no versão prévia do recurso.

Executando consulta de pesquisa de similaridade vetorial

Depois de criar um contêiner com a política vetorial desejada e inserir dados vetoriais no contêiner, você poderá realizar uma busca em vetores usando a função do sistema Distância vetorial em uma consulta. Suponha que você queira pesquisar livros sobre receitas de comida olhando a descrição. Primeiro você precisa obter os embeddings para o texto da sua consulta. Nesse caso, você pode querer gerar embeddings para o texto da consulta – “receita de comida”. Depois de incorporar a sua consulta de pesquisa, você pode usá-la na função VectorDistance na consulta de busca em vetores e obter todos os itens semelhantes à sua consulta, conforme mostrado aqui:

SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10]) AS SimilarityScore   
FROM c  
ORDER BY VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10])   

Essa consulta recupera os títulos dos livros junto com as pontuações de similaridade em relação à sua consulta. Aqui está um exemplo em Java:

float[] embedding = new float[10];
for (int i = 0; i < 10; i++) {
    array[i] = i + 1;
}
ArrayList<SqlParameter> paramList = new ArrayList<SqlParameter>();
  paramList.add(new SqlParameter("@embedding", embedding));
  SqlQuerySpec querySpec = new SqlQuerySpec("SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore  FROM c ORDER BY VectorDistance(c.contentVector,@embedding)", paramList);
  CosmosPagedIterable<Family> filteredFamilies = container.queryItems(querySpec, new CosmosQueryRequestOptions(), Family.class);

  if (filteredFamilies.iterator().hasNext()) {
      Family family = filteredFamilies.iterator().next();
      logger.info(String.format("First query result: Family with (/id, partition key) = (%s,%s)",family.getId(),family.getLastName()));
  }

Próximas etapas