Índice
Uma das características principais do Qdrant é a combinação eficaz de índice de vetores e índice tradicional. Isso é crucial, pois somente ter um índice de vetores não é suficiente para possibilitar uma busca eficiente de vetores sob condições de filtro. Em termos simples, o índice de vetores acelera a busca de vetores, enquanto o índice de carga acelera o filtro.
O índice dentro de um parágrafo existe de forma independente, mas os parâmetros do índice em si são configurados para o conjunto inteiro.
Nem todos os parágrafos têm índices automaticamente. Isso depende dos requisitos das configurações de otimização e geralmente depende do número de pontos armazenados.
Índice de Carga
O índice de carga no Qdrant é semelhante ao índice em um banco de dados orientado a documentos tradicional. Este índice é construído para campos e tipos específicos, utilizados para recuperar rapidamente pontos com base em condições de filtro correspondentes.
Também é usado para estimar com precisão a cardinalidade das condições de filtro, o que ajuda o planejador de consultas a escolher estratégias de busca.
Criar um índice requer recursos computacionais e memória adicionais, portanto, é crucial escolher cuidadosamente os campos a serem indexados. O Qdrant não faz essa escolha por você, mas sim a delega ao usuário.
Para marcar um campo como indexável, o seguinte método pode ser utilizado:
PUT /collections/{nome_da_coleção}/index
{
"nome_do_campo": "nome do campo a ser indexado",
"esquema_do_campo": "keyword"
}
Os tipos de campos disponíveis são:
-
keyword
- para carga de palavras-chave, afetando condições de filtro correspondentes. -
integer
- para carga de números inteiros, afetando condições de correspondência e de intervalo. -
float
- para carga de números de ponto flutuante, afetando condições de intervalo. -
bool
- para carga booleana, afetando condições de filtro correspondentes (disponível a partir da versão 1.4.0). -
geo
- para carga geográfica, afetando caixas delimitadoras geográficas e condições de filtro de raio geográfico. -
text
- um tipo especial de índice adequado para carga de palavras-chave/string, afetando condições de busca em texto completo.
Os índices de carga podem consumir memória adicional, portanto, é recomendável indexar apenas os campos utilizados em condições de filtro. Se for necessário filtrar com base em muitos campos e as restrições de memória não permitirem que todos sejam indexados, é aconselhável escolher os campos que mais limitam os resultados da busca. Geralmente, quanto mais valores únicos um valor de carga possui, mais eficaz será o uso do índice.
Índice de Texto Completo
Disponível a partir da versão 0.10.0
O Qdrant suporta busca em texto completo para cargas de string. O índice de texto completo permite filtrar pontos com base na presença de palavras ou frases no campo de carga.
Configurar um índice de texto completo é ligeiramente complexo porque você pode especificar parâmetros de tokenização. A tokenização é o processo de dividir uma string em tokens e em seguida indexar esses tokens em um índice invertido.
Para criar um índice de texto completo, você pode usar o seguinte método:
PUT /collections/{nome_da_coleção}/index
{
"nome_do_campo": "nome do campo a ser indexado",
"esquema_do_campo": {
"tipo": "text",
"tokenizador": "word",
"comprimento_mínimo_do_token": 2,
"comprimento_máximo_do_token": 20,
"minúsculas": true
}
}
Os métodos de tokenização disponíveis são:
-
word
- Separa a string com base em espaços, pontuação e caracteres especiais. -
whitespace
- Separa a string com base em espaços. -
prefix
- Separa a string com base em espaços, pontuação e caracteres especiais, em seguida cria um índice de prefixo para cada palavra. Por exemplo,hello
será indexado comoh
,he
,hel
,hell
,hello
. -
multilingual
- Um tipo especial de tokenização baseado no pacote charabia. Ele permite a tokenização e lematização corretas de várias línguas, incluindo línguas com alfabetos não latinos e separadores não espaciais. Consulte a documentação do charabia para uma lista completa de idiomas suportados e opções de normalização. Na configuração de compilação padrão, o Qdrant não inclui suporte para todos os idiomas, pois isso aumentaria o tamanho dos arquivos binários. Chinês, japonês e coreano não estão habilitados por padrão, mas podem ser ativados compilando o Qdrant a partir do código-fonte usando as flags--features multiling-chinese, multiling-japanese, multiling-korean
.
Consulte os exemplos de correspondência em texto completo para um exemplo do uso de um índice de texto completo para consultas.
Indexação de Vetores
A indexação de vetores é uma estrutura de dados baseada em vetores, construída através de modelos matemáticos específicos. Com a indexação de vetores, podemos consultar eficientemente múltiplos vetores semelhantes ao vetor alvo.
Atualmente, o Qdrant apenas utiliza o HNSW como índice de vetores.
HNSW (Hierarchical Navigable Small World Graph) é um algoritmo de indexação baseado em grafos. De acordo com regras específicas, ele constrói uma estrutura de navegação de múltiplas camadas para o grafo. Nesta estrutura, as camadas superiores são mais espaçadas, com maiores distâncias entre os nós. As camadas inferiores são mais densas, com distâncias menores entre os nós. A busca começa a partir da camada superior, encontrando o nó mais próximo ao alvo nesta camada e então entrando na próxima camada para outra busca. Após múltiplas iterações, é possível se aproximar rapidamente da posição alvo.
Para melhoria de desempenho, o HNSW limita o grau máximo dos nós em cada camada do grafo para m
. Além disso, é possível especificar o intervalo de busca usando ef_construct
(durante a construção do índice) ou ef
(enquanto busca o alvo).
Estes parâmetros podem ser configurados no arquivo de configuração:
armazenamento:
hnsw_index:
m: 16
ef_construct: 100
full_scan_threshold: 10000
Durante o processo de criação da coleção, o parâmetro ef
pode ser configurado e, por padrão, é igual a ef_construct
.
O HNSW foi escolhido por várias razões. Em primeiro lugar, o HNSW é altamente compatível com permitir que o Qdrant modifique filtros durante o processo de busca. Em segundo lugar, de acordo com testes de benchmark públicos, é um dos algoritmos mais precisos e rápidos.
Disponível a partir da v1.1.1
Os parâmetros do HNSW também podem ser ajustados para coleções e vetores nomeados para otimizar o desempenho da busca, configurando hnsw_config
.
Índice Filtrável
Índices de carga separados e índices de vetores sozinhos não podem atender plenamente o uso de filtros para pesquisa.
Nos casos em que os filtros são fracos, o índice HNSW pode ser usado diretamente. Nos casos em que os filtros são estritos, o índice de carga pode ser usado e completamente classificado novamente. No entanto, em casos intermediários, este método é ineficaz.
Por um lado, não podemos realizar uma verificação completa em muitos vetores. Por outro lado, ao usar filtros excessivamente estritos, o grafo HNSW começa a se desintegrar.
Bordas adicionais permitem que você use eficientemente o índice HNSW para pesquisar vetores vizinhos e aplicar filtros durante a busca no grafo.
Esta abordagem minimiza o overhead de verificações de condições, pois você só precisa calcular as condições para uma pequena parte dos pontos que participam da busca.