Repositório de vetores no Azure Cosmos DB for MongoDB vCore

APLICA-SE AO: MongoDB vCore

Use o banco de dados de vetores integrado do Azure Cosmos DB for MongoDB vCore para conectar perfeitamente seus aplicativos baseados em IA aos seus dados que estão armazenados no Azure Cosmos DB. Essa integração pode incluir aplicativos criados usando inserções OpenAI do Azure. O banco de dados de vetores integrado nativamente permite armazenar, indexar e consultar com eficiência dados de vetores de alta dimensão armazenados diretamente no Azure Cosmos DB for MongoDB vCore, juntamente com os dados originais a partir dos quais os dados de vetores são criados. Ele elimina a necessidade de transferir seus dados para repositórios de vetores alternativos e gerar custos adicionais.

O que é um repositório de vetores?

Um repositório de vetores é um banco de dados de vetores projetado para armazenar e gerenciar inserções de vetores, que são representações matemáticas de dados em um espaço altamente dimensional. Nesse espaço, cada dimensão corresponde a um recurso dos dados e dezenas de milhares de dimensões podem ser usadas para representar dados sofisticados. A posição de um vetor nesse espaço representa as características dele. Palavras, frases ou documentos inteiros e imagens, áudio e outros tipos de dados podem ser vetorizados.

Como funciona um repositório de vetores?

Em um repositório de vetores, algoritmos de busca em vetores são usados para indexar e consultar inserções. Alguns algoritmos de busca em vetores conhecidos incluem HNSW (Hierarchical Navigable Small World), IVF (Arquivo Invertido), DiskANN etc. A busca em vetores é um método que ajuda a localizar itens semelhantes com base em suas características de dados, em vez de correspondências exatas em um campo de propriedade. Essa técnica é útil em usos como pesquisa de texto semelhante, localização de imagens relacionadas, recomendações ou até mesmo detecção de anomalias. Ela é usada para consultar as inserções de vetores (listas de números) dos seus dados que você criou usando um modelo de machine learning por meio de uma API de inserções. Exemplos de APIs de inserções são Inserções do Azure OpenAI ou Hugging Face no Azure. A busca em vetores mede a distância entre os vetores de dados e o vetor de consulta. Os vetores de dados mais próximos do vetor de consulta são os mais semelhantes semanticamente.

No Banco de Dados de vetores integrado do Azure Cosmos DB for MongoDB vCore, as inserções podem ser armazenadas, indexadas e consultadas junto com os dados originais. Essa abordagem elimina o custo extra de replicação de dados em um banco de dados vetoriais puro separado. Além disso, essa arquitetura mantém as inserções vetoriais e os dados originais juntos, o que facilita melhor as operações de dados multimodais e possibilita maior consistência, escala e desempenho de dados.

Criar um índice de vetor

Para executar a pesquisa de similaridade de vetor sobre as propriedades de vetor em seus documentos, primeiro você precisará criar um índice de vetor.

Criar um índice de vetor usando HNSW

Você pode criar índices (Hierarchical Navigable Small World) em camadas de cluster M40 e superiores. Para criar o índice HSNW, é necessário criar um índice de vetor com o parâmetro "kind" definido como "vector-hnsw" seguindo o modelo abaixo:

{ 
    "createIndexes": "<collection_name>",
    "indexes": [
        {
            "name": "<index_name>",
            "key": {
                "<path_to_property>": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": <integer_value>, 
                "efConstruction": <integer_value>, 
                "similarity": "<string_value>", 
                "dimensions": <integer_value> 
            } 
        } 
    ] 
}
Campo Type Descrição
index_name string Nome exclusivo do índice.
path_to_property string Caminho para a propriedade que contém o vetor. Esse caminho pode ser uma propriedade de nível superior ou um caminho de notação de ponto para a propriedade. Se um caminho de notação de ponto for usado, todos os elementos não-folha não poderão ser matriz. Os vetores devem ser um number[] para serem indexados e retornados nos resultados da pesquisa de vetor.
kind string Tipo de índice de vetor a ser criado. As opções são vector-ivf e vector-hnsw. Observe que vector-ivf está disponível em todas as camadas de cluster e vector-hnsw está disponível em camadas de cluster M40 e superiores.
m Número inteiro O número máximo de conexões por camada (16 por padrão, o valor mínimo é 2, o valor máximo é 100). M superior é adequado para conjuntos de dados com requisitos de alta dimensionalidade e/ou alta precisão.
efConstruction Número inteiro O tamanho da lista de candidatos dinâmicos para construir o grafo (64 por padrão, o valor mínimo é 4, o valor máximo é 1000). Uma efConstruction mais alta resultará em melhor qualidade de índice e maior precisão, mas também aumentará o tempo necessário para criar o índice. efConstruction deve ser pelo menos 2 * m
similarity string Métrica de similaridade a ser usada com o índice. As opções possíveis são COS (distância do cosseno), L2 (distância euclidiana) e IP (produto interno).
dimensions inteiro Número de dimensões para similaridade de vetor. O número máximo de dimensões com suporte é 2000.

Faça uma busca em vetores com HNSW

Para realizar uma busca em vetores, use a fase do pipeline de agregação $search em uma consulta com o operador cosmosSearch.

{
    "$search": {
        "cosmosSearch": {
            "vector": <query_vector>,
            "path": "<path_to_property>",
            "k": <num_results_to_return>,
            "efSearch": <integer_value>
        },
    }
  }
}

Campo Type Descrição
efSearch Número inteiro O tamanho da lista de candidatos dinâmicos para pesquisa (40 por padrão). Um valor mais alto fornece melhor recall ao custo da velocidade.
k Número inteiro O número de resultados a serem retornados. deve ser menor ou igual a efSearch

Observação

A criação de um índice HSNW com grandes conjuntos de dados pode resultar no esgotamento de memória do recurso vCore do Azure Cosmos DB for MongoDB ou na limitação do desempenho de outras operações em execução no banco de dados. Se você encontrar esses problemas, eles poderão ser mitigados dimensionando seu recurso para uma camada de cluster mais alta ou reduzindo o tamanho do conjunto de dados.

Criar um índice de vetor usando IVF

Para criar um índice de vetor usando o algoritmo IVF (Arquivo Invertido), utilize o modelo createIndexes a seguir e defina o parâmetro "kind" como "vector-ivf":

{
  "createIndexes": "<collection_name>",
  "indexes": [
    {
      "name": "<index_name>",
      "key": {
        "<path_to_property>": "cosmosSearch"
      },
      "cosmosSearchOptions": {
        "kind": "vector-ivf",
        "numLists": <integer_value>,
        "similarity": "<string_value>",
        "dimensions": <integer_value>
      }
    }
  ]
}
Campo Type Descrição
index_name string Nome exclusivo do índice.
path_to_property string Caminho para a propriedade que contém o vetor. Esse caminho pode ser uma propriedade de nível superior ou um caminho de notação de ponto para a propriedade. Se um caminho de notação de ponto for usado, todos os elementos não-folha não poderão ser matriz. Os vetores devem ser um number[] para serem indexados e retornados nos resultados da pesquisa de vetor.
kind string Tipo de índice de vetor a ser criado. As opções são vector-ivf e vector-hnsw. Observe que vector-ivf está disponível em todas as camadas de cluster e vector-hnsw está disponível em camadas de cluster M40 e superiores.
numLists Número inteiro Esse número inteiro é o número de clusters que o índice de arquivo invertido (IVF) usa para agrupar os dados vetoriais. Recomendamos que numLists seja definido como documentCount/1000 para até 1 milhão de documentos e como sqrt(documentCount) para mais de 1 milhão de documentos. Usar um numLists valor de 1 é semelhante a realizar uma pesquisa de força bruta, que terá desempenho limitado.
similarity string Métrica de similaridade a ser usada com o índice. As opções possíveis são COS (distância do cosseno), L2 (distância euclidiana) e IP (produto interno).
dimensions inteiro Número de dimensões para similaridade de vetor. O número máximo de dimensões com suporte é 2000.

Importante

É importante definir o parâmetro numLists corretamente para obter uma boa precisão e desempenho. Recomendamos que numLists seja definido como documentCount/1000 para até 1 milhão de documentos e como sqrt(documentCount) para mais de 1 milhão de documentos.

À medida que o número de itens no banco de dados aumenta, você deve ajustar numLists para que seja maior para obter um bom desempenho de latência para a busca em vetores.

Se você estiver testando um novo cenário ou criando uma pequena demonstração, poderá começar com numLists definido como 1 para executar uma pesquisa de força bruta em todos os vetores. Isso deve lhe fornecer resultados mais precisos da busca em vetores, mas esteja ciente de que a velocidade e a latência da busca serão lentas. Após a configuração inicial, você deve seguir em frente e ajustar o parâmetro numLists usando as diretrizes acima.

Fazer uma busca em vetores com IVF

Para realizar uma pesquisa de vetor, use a fase do pipeline de agregação $search em uma consulta MongoDB. Para usar o índice cosmosSearch, use o novo operador cosmosSearch.

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <query_vector>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

Para recuperar a pontuação de similaridade (searchScore) junto com os documentos encontrados pela busca em vetores, use o operador $project para incluir searchScore e altere o nome dele para <custom_name_for_similarity_score> nos resultados. Em seguida, o documento também é projetado como objeto aninhado. Observe que a pontuação de similaridade é calculada usando a métrica definida no índice de vetor.

Importante

Os vetores devem ser um number[] a ser indexado. O uso de outro tipo, como double[], impede que o documento seja indexado. Os documentos não indexados não serão retornados no resultado de uma pesquisa de vetor.

Exemplo usando um índice HNSW.

Os exemplos a seguir mostram como indexar vetores, adicionar documentos que possuem propriedades de vetor, realizar uma pesquisa de vetores e recuperar a configuração do índice.

use test;

db.createCollection("exampleCollection");

db.runCommand({ 
    "createIndexes": "exampleCollection",
    "indexes": [
        {
            "name": "VectorSearchIndex",
            "key": {
                "contentVector": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": 16, 
                "efConstruction": 64, 
                "similarity": "COS", 
                "dimensions": 3
            } 
        } 
    ] 
});

Esse comando cria um índice HNSW na propriedade contentVector nos documentos armazenados na coleção especificada, exampleCollection. A propriedade cosmosSearchOptions especifica os parâmetros do índice de vetor HNSW. Se o seu documento tiver o vetor armazenado em uma propriedade aninhada, você poderá definir essa propriedade usando um caminho de notação de ponto. Por exemplo, você pode usar text.contentVector se contentVector for uma subpropriedade de text.

Adicionando vetores ao banco de dados

Para adicionar vetores à coleção de seu banco de dados, primeiro você precisa criar as incorporações usando seu próprio modelo, Incorporações OpenAI do Azure ou outra API (como Hugging Face no Azure). Neste exemplo, novos documentos são adicionados por meio de inserções de amostra:

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

Continuando com o último exemplo, crie outro vetor, queryVector. A pesquisa de vetor mede a distância entre queryVector e os vetores no caminho contentVector dos documentos. Você pode definir o número de resultados que a pesquisa retorna definindo o parâmetro k, que é definido 2 aqui. Você também pode definir efSearch, que é um inteiro que controla o tamanho da lista de vetores candidatos. Um valor mais alto pode melhorar a precisão, no entanto, a pesquisa será mais lenta como consequência. Esse é um parâmetro opcional, com um valor padrão de 40.

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    "$search": {
        "cosmosSearch": {
            "vector": "queryVector",
            "path": "contentVector",
            "k": 2,
            "efSearch": 40
        },
    }
  }
}
]);

Nesse exemplo, uma pesquisa de vetor é executada usando queryVector como entrada por meio do shell do Mongo. O resultado da pesquisa é uma lista de dois itens mais semelhantes ao vetor de consulta, classificados por suas pontuações de similaridade.

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

Obter definições de índice de vetor

Para recuperar sua definição de índice vetorial da coleção, use o comando listIndexes:

db.exampleCollection.getIndexes();

Nesse exemplo, vectorIndex é retornado com todos os parâmetros cosmosSearch que foram utilizados para criar o índice:

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { contentVector: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-hnsw',
      m: 40,
      efConstruction: 64
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

Exemplo usando um índice de IVF

Os exemplos a seguir mostram como indexar vetores, adicionar documentos que possuem propriedades de vetor, realizar uma pesquisa de vetores e recuperar a configuração do índice.

Criar um índice de vetor

use test;

db.createCollection("exampleCollection");

db.runCommand({
  createIndexes: 'exampleCollection',
  indexes: [
    {
      name: 'vectorSearchIndex',
      key: {
        "vectorContent": "cosmosSearch"
      },
      cosmosSearchOptions: {
        kind: 'vector-ivf',
        numLists: 3,
        similarity: 'COS',
        dimensions: 3
      }
    }
  ]
});

Esse comando cria um índice vector-ivf na propriedade vectorContent nos documentos armazenados na coleção especificada, exampleCollection. A propriedade cosmosSearchOptions especifica os parâmetros do índice de vetor IVF. Se o seu documento tiver o vetor armazenado em uma propriedade aninhada, você poderá definir essa propriedade usando um caminho de notação de ponto. Por exemplo, você pode usar text.vectorContent se vectorContent for uma subpropriedade de text.

Adicionando vetores ao banco de dados

Para adicionar vetores à coleção de seu banco de dados, primeiro você precisa criar as incorporações usando seu próprio modelo, Incorporações OpenAI do Azure ou outra API (como Hugging Face no Azure). Neste exemplo, novos documentos são adicionados por meio de inserções de amostra:

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

Faça uma pesquisa vetorial

Para realizar uma pesquisa de vetor, use a fase do pipeline de agregação $search em uma consulta MongoDB. Para usar o índice cosmosSearch, use o novo operador cosmosSearch.

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <vector_to_search>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

Para recuperar a pontuação de similaridade (searchScore) junto com os documentos encontrados pela busca em vetores, use o operador $project para incluir searchScore e altere o nome dele para <custom_name_for_similarity_score> nos resultados. Em seguida, o documento também é projetado como objeto aninhado. Observe que a pontuação de similaridade é calculada usando a métrica definida no índice de vetor.

Continuando com o último exemplo, crie outro vetor, queryVector. A pesquisa de vetor mede a distância entre queryVector e os vetores no caminho vectorContent dos documentos. Você pode definir o número de resultados que a pesquisa retorna definindo o parâmetro k, que é definido 2 aqui. Você também pode definir nProbes, que é um inteiro que controla o número de clusters próximos que são inspecionados em cada pesquisa. Um valor mais alto pode melhorar a precisão, no entanto, a pesquisa será mais lenta como consequência. Esse é um parâmetro opcional com um valor padrão de 1, e não pode ser maior que o valor numLists especificado no índice de vetor.

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    $search: {
      "cosmosSearch": {
        "vector": queryVector,
        "path": "vectorContent",
        "k": 2
      },
    "returnStoredSource": true }},
  {
    "$project": { "similarityScore": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
]);

Nesse exemplo, uma pesquisa de vetor é executada usando queryVector como entrada por meio do shell do Mongo. O resultado da pesquisa é uma lista de dois itens mais semelhantes ao vetor de consulta, classificados por suas pontuações de similaridade.

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

Obter definições de índice de vetor

Para recuperar sua definição de índice vetorial da coleção, use o comando listIndexes:

db.exampleCollection.getIndexes();

Nesse exemplo, vectorIndex é retornado com todos os parâmetros cosmosSearch que foram utilizados para criar o índice:

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { vectorContent: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-ivf',
      numLists: 3,
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

Busca em vetores filtrada (versão prévia)

Agora é possível executar buscas em vetores com qualquer filtro de consulta com suporte, como $lt, $lte, $eq, $neq, $gte, $gt, $in, $nin e $regex. Habilite o recurso "filtragem de busca em vetores" na guia "Versões prévias do recurso" da sua Assinatura do Azure. Saiba mais sobre as versões prévias do recurso aqui.

Primeiro, você precisará definir um índice para o filtro, além de um índice de vetor. Por exemplo, você pode definir o índice de filtro em uma propriedade

db.runCommand({ 
     "createIndexes": "<collection_name",
    "indexes": [ {
        "key": { 
            "<property_to_filter>": 1 
               }, 
        "name": "<name_of_filter_index>" 
    }
    ] 
});

Em seguida, você pode adicionar o termo "filter" à sua busca em vetores, conforme mostrado abaixo. Neste exemplo, o filtro está procurando documentos em que a propriedade "title" não esteja na lista de ["not in this text", "or this text"].


db.exampleCollection.aggregate([
  {
      '$search': {
          "cosmosSearch": {
              "vector": "<query_vector>",
              "path": <path_to_vector>,
              "k": num_results,
              "filter": {<property_to_filter>: {"$nin": ["not in this text", "or this text"]}}
          },
          "returnStoredSource": True }},
      {'$project': { 'similarityScore': { '$meta': 'searchScore' }, 'document' : '$$ROOT' }
}
]);

Importante

Durante a versão prévia, a busca em vetores filtrada pode exigir um ajuste dos parâmetros de índice de vetor para obter maior precisão. Por exemplo, aumentar m, efConstruction ou efSearch ao usar HNSW, ou numLists, ou nProbes ao usar IVF, pode levar a melhores resultados. Você deve testar sua configuração antes do uso para garantir que os resultados sejam satisfatórios.

Usar ferramentas de Orquestração LLM

Usar como um banco de dados de vetor com Kernel Semântico

Use o Kernel Semântico para orquestrar sua recuperação de informações do vCore do Azure Cosmos DB for MongoDB e seu LLM. Saiba mais aqui.

https://github.com/microsoft/semantic-kernel/tree/main/python/semantic_kernel/connectors/memory/azure_cosmosdb

Usar como um banco de dados de vetores com LangChain

Use o LangChain para orquestrar sua recuperação de informações do vCore do Azure Cosmos DB for MongoDB e seu LLM. Saiba mais aqui.

Usar como um cache semântico com LangChain

Use o LangChain e o Azure Cosmos DB for MongoDB (vCore) para orquestrar o Cache Semântico, usando repositórios LLM gravados anteriormente que podem economizar custos da API de LLM e reduzir a latência para respostas. Saiba mais aqui

Recursos e limitações

  • Métricas de distância com suporte: L2 (Euclidiano), produto escalar e cosseno.
  • Métodos de indexação com suporte: IVFFLAT (GA) e HSNW (versão prévia)
  • Indexação de vetores de até 2.000 dimensões de tamanho.
  • A indexação se aplica a apenas um vetor por caminho.
  • Somente um índice pode ser criado por caminho de vetor.

Resumo

Esse guia demonstra como criar um índice vetorial, adicionar documentos que tenham dados vetoriais, realizar uma pesquisa de similaridade e recuperar a definição do índice. Usando o banco de dados de vetores integrado, você pode armazenar, indexar e consultar com eficiência dados vetoriais altamente dimensionais diretamente no Azure Cosmos DB for MongoDB vCore. Ele permite que você aproveite todo o potencial dos seus dados por meio de inserções de vetores e capacita você a criar aplicativos mais precisos, eficientes e sofisticados.

Próxima etapa