Apresentando o Milvus Ngram Index: Correspondência mais rápida de palavras-chave e consultas LIKE para cargas de trabalho de agentes
Nos sistemas de agentes, a recuperação de contexto é um elemento fundamental em todo o pipeline, fornecendo a base para o raciocínio, o planeamento e a ação a jusante. A pesquisa vetorial ajuda os agentes a recuperar contexto semanticamente relevante que capta a intenção e o significado em conjuntos de dados grandes e não estruturados. No entanto, a relevância semântica, por si só, muitas vezes não é suficiente. Os pipelines de agentes também dependem da pesquisa de texto completo para impor restrições de palavras-chave exactas - tais como nomes de produtos, chamadas de funções, códigos de erro ou termos legalmente significativos. Esta camada de suporte garante que o contexto recuperado não só é relevante, mas também satisfaz explicitamente os requisitos textuais rígidos.
As cargas de trabalho reais reflectem consistentemente esta necessidade:
Os assistentes de apoio ao cliente têm de encontrar conversas que mencionem um produto ou ingrediente específico.
Os copilotos de codificação procuram trechos que contenham um nome de função exato, uma chamada de API ou uma cadeia de erros.
Os agentes jurídicos, médicos e académicos filtram os documentos em busca de cláusulas ou citações que devem aparecer textualmente.
Tradicionalmente, os sistemas têm tratado esta questão com o operador SQL LIKE. Uma consulta como name LIKE '%rod%' é simples e amplamente suportada, mas sob alta concorrência e grandes volumes de dados, esta simplicidade acarreta grandes custos de desempenho.
Sem um índice, uma consulta
LIKEpercorre todo o armazenamento de contexto e aplica a correspondência de padrões linha a linha. Com milhões de registos, mesmo uma única consulta pode demorar segundos - demasiado lenta para interações de agentes em tempo real.Mesmo com um índice invertido convencional, padrões curinga como
%rod%continuam difíceis de otimizar porque o mecanismo ainda deve percorrer todo o dicionário e executar a correspondência de padrões em cada entrada. A operação evita a varredura de linhas, mas permanece fundamentalmente linear, resultando em melhorias apenas marginais.
Isto cria uma lacuna clara nos sistemas de recuperação híbridos: a pesquisa vetorial lida com a relevância semântica de forma eficiente, mas a filtragem de palavras-chave exactas torna-se frequentemente o passo mais lento no processo.
O Milvus suporta nativamente a pesquisa vetorial e de texto integral híbrida com filtragem de metadados. Para resolver as limitações da correspondência de palavras-chave, o Milvus introduz o Índice Ngram, que melhora o desempenho do LIKE dividindo o texto em pequenas substrings e indexando-as para uma pesquisa eficiente. Isto reduz drasticamente a quantidade de dados examinados durante a execução da consulta, fornecendo consultas LIKE dezenas a centenas de vezes mais rápidas em cargas de trabalho autênticas.
O restante deste post mostra como o Índice Ngram funciona no Milvus e avalia seu desempenho em cenários do mundo real.
O que é o índice Ngram?
Nas bases de dados, a filtragem de texto é normalmente expressa usando SQL, a linguagem de consulta padrão usada para recuperar e gerenciar dados. Um dos operadores de texto mais utilizados é LIKE, que suporta a correspondência de cadeias de caracteres baseada em padrões.
As expressões LIKE podem ser amplamente agrupadas em quatro tipos de padrões comuns, dependendo da forma como os caracteres curinga são utilizados:
Correspondência infixa (
name LIKE '%rod%'): Corresponde a registos onde a substring rod aparece em qualquer parte do texto.Correspondência de prefixo (
name LIKE 'rod%'): Corresponde aos registos cujo texto começa com rod.Correspondência de sufixo (
name LIKE '%rod'): Corresponde aos registos cujo texto termina com rod.Correspondência curinga (
name LIKE '%rod%aab%bc_de'): Combina várias condições de substring (%) com curingas de um único carácter (_) num único padrão.
Embora esses padrões sejam diferentes em aparência e expressividade, o Índice Ngram em Milvus acelera todos eles usando a mesma abordagem subjacente.
Antes de construir o índice, Milvus divide cada valor de texto em substrings curtas e sobrepostas de comprimentos fixos, conhecidas como n-gramas. Por exemplo, quando n = 3, a palavra "Milvus" é decomposta nos seguintes 3-gramas: "Mil", "ilv", "lvu" e "vus". Cada n-grama é então armazenado num índice invertido que mapeia a substring para o conjunto de IDs de documentos em que aparece. No momento da consulta, as condições de LIKE são traduzidas em combinações de pesquisas de n-gramas, permitindo ao Milvus filtrar rapidamente a maioria dos registos não correspondentes e avaliar o padrão em relação a um conjunto de candidatos muito mais pequeno. É isto que transforma as dispendiosas pesquisas de cadeias de caracteres em eficientes consultas baseadas em índices.
Dois parâmetros controlam a forma como o índice Ngram é construído: min_gram e max_gram. Juntos, eles definem o intervalo de comprimentos de substring que o Milvus gera e indexa.
min_gram: O comprimento de substring mais curto a indexar. Na prática, isso também define o comprimento mínimo da substring da consulta que pode se beneficiar do Índice Ngrammax_gram: O comprimento mais longo da substring a indexar. No momento da consulta, determina adicionalmente o tamanho máximo da janela utilizada ao dividir cadeias de caracteres de consulta mais longas em n-gramas.
Ao indexar todas as substrings contíguas cujos comprimentos se situam entre min_gram e max_gram, Milvus estabelece uma base consistente e eficiente para acelerar todos os tipos de padrões LIKE suportados.
Como funciona o índice Ngram?
Milvus implementa o Índice Ngram em um processo de duas fases:
Construir o índice: Gerar n-gramas para cada documento e construir um índice invertido durante a ingestão de dados.
Acelerar as consultas: Utilizar o índice para limitar a pesquisa a um pequeno conjunto de candidatos e, em seguida, verificar as correspondências
LIKEexactas desses candidatos.
Um exemplo concreto torna este processo mais fácil de compreender.
Fase 1: Construir o índice
Decompor o texto em n-gramas:
Suponhamos que indexamos o texto "Apple" com as seguintes definições:
min_gram = 2max_gram = 3
Com esta configuração, o Milvus gera todas as substrings contíguas de comprimento 2 e 3:
2-gramas:
Ap,pp,pl,le3-gramas:
App,ppl,ple
Construir um índice invertido:
Consideremos agora um pequeno conjunto de dados com cinco registos:
Documento 0:
AppleDocumento 1:
PineappleDocumento 2:
MapleDocumento 3:
ApplyDocumento 4:
Snapple
Durante a ingestão, o Milvus gera n-gramas para cada registo e insere-os num índice invertido. Neste índice:
As chaves são n-gramas (substrings)
Os valores são listas de IDs de documentos onde o n-grama aparece
"Ap" -> [0, 3]
"App" -> [0, 3]
"Ma" -> [2]
"Map" -> [2]
"Pi" -> [1]
"Pin" -> [1]
"Sn" -> [4]
"Sna" -> [4]
"ap" -> [1, 2, 4]
"apl" -> [2]
"app" -> [1, 4]
"ea" -> [1]
"eap" -> [1]
"in" -> [1]
"ine" -> [1]
"le" -> [0, 1, 2, 4]
"ly" -> [3]
"na" -> [4]
"nap" -> [4]
"ne" -> [1]
"nea" -> [1]
"pl" -> [0, 1, 2, 3, 4]
"ple" -> [0, 1, 2, 4]
"ply" -> [3]
"pp" -> [0, 1, 3, 4]
"ppl" -> [0, 1, 3, 4]
Agora o índice está totalmente construído.
Fase 2: Acelerar as consultas
Quando um filtro LIKE é executado, o Milvus utiliza o índice Ngram para acelerar a avaliação da consulta através dos seguintes passos:
1. Extrair o termo da consulta: Substrings contíguos sem curingas são extraídos da expressão LIKE (por exemplo, '%apple%' torna-se apple).
2. Decompor o termo de consulta: O termo de consulta é decomposto em n-gramas com base no seu comprimento (L) e nos min_gram e max_gram configurados.
3. Procurar cada grama e intersectar: Milvus procura os n-gramas da consulta no índice invertido e intersecta as suas listas de identificação de documentos para produzir um pequeno conjunto de candidatos.
4. Verificar e devolver resultados: A condição original LIKE é aplicada apenas a este conjunto de candidatos para determinar o resultado final.
Na prática, a forma como uma consulta é dividida em n-gramas depende da forma do próprio padrão. Para ver como isto funciona, vamos concentrar-nos em dois casos comuns: correspondências de infixos e correspondências de wildcards. As correspondências de prefixo e sufixo comportam-se da mesma forma que as correspondências de infixo, pelo que não as iremos abordar separadamente.
Correspondência infixa
Para uma correspondência infixa, a execução depende do comprimento da substring literal (L) em relação a min_gram e max_gram.
1. min_gram ≤ L ≤ max_gram (por exemplo, strField LIKE '%ppl%')
A substring literal ppl está inteiramente dentro do intervalo de n-gramas configurado. Milvus procura diretamente o n-grama "ppl" no índice invertido, produzindo os IDs de documentos candidatos [0, 1, 3, 4].
Como o próprio literal é um n-grama indexado, todos os candidatos já satisfazem a condição de infixação. O passo final de verificação não elimina nenhum registo, e o resultado permanece [0, 1, 3, 4].
2. L > max_gram (e.g., strField LIKE '%pple%')
A substring literal pple é mais comprida do que max_gram, pelo que é decomposta em n-gramas sobrepostos utilizando uma janela de tamanho max_gram. Com max_gram = 3, isto produz os n-gramas "ppl" e "ple".
O Milvus procura cada n-grama no índice invertido:
"ppl"→[0, 1, 3, 4]"ple"→[0, 1, 2, 4]
A intersecção destas listas dá origem ao conjunto de candidatos [0, 1, 4]. O filtro LIKE '%pple%' original é então aplicado a estes candidatos. Todos os três satisfazem a condição, pelo que o resultado final permanece [0, 1, 4].
3. L < min_gram (e.g., strField LIKE '%pp%')
A substring literal é mais curta do que min_gram e, por conseguinte, não pode ser decomposta em n-gramas indexados. Neste caso, o índice Ngram não pode ser utilizado e o Milvus volta ao caminho de execução predefinido, avaliando a condição LIKE através de uma pesquisa completa com correspondência de padrões.
Correspondência com curinga (por exemplo, strField LIKE '%Ap%pple%')
Este padrão contém vários caracteres curinga, pelo que o Milvus começa por dividi-lo em literais contíguos: "Ap" e "pple".
Milvus então processa cada literal independentemente:
"Ap"tem comprimento 2 e está dentro do intervalo de n-gramas."pple"é mais longo do quemax_grame é decomposto em"ppl"e"ple".
Isto reduz a consulta aos seguintes n-gramas:
"Ap"→[0, 3]"ppl"→[0, 1, 3, 4]"ple"→[0, 1, 2, 4]
A intersecção destas listas produz um único candidato: [0].
Finalmente, o filtro original LIKE '%Ap%pple%' é aplicado ao documento 0 ("Apple"). Uma vez que não satisfaz o padrão completo, o conjunto final de resultados está vazio.
Limitações e compromissos do índice de ngramas
Embora o índice Ngram possa melhorar significativamente o desempenho da consulta LIKE, introduz compensações que devem ser consideradas em implementações no mundo real.
- Aumento do tamanho do índice
O principal custo do índice Ngram é o aumento da sobrecarga de armazenamento. Como o índice armazena todas as substrings contíguas cujos comprimentos estão entre min_gram e max_gram, o número de n-gramas gerados cresce rapidamente à medida que esse intervalo se expande. Cada comprimento adicional de n-grama adiciona efetivamente outro conjunto completo de substrings sobrepostas para cada valor de texto, aumentando tanto o número de chaves de índice como as suas listas de lançamento. Na prática, expandir o intervalo em apenas um caractere pode praticamente dobrar o tamanho do índice em comparação com um índice invertido padrão.
- Não é eficaz para todas as cargas de trabalho
O índice Ngram não acelera todas as cargas de trabalho. Se os padrões de consulta forem altamente irregulares, contiverem literais muito curtos ou não conseguirem reduzir o conjunto de dados a um pequeno conjunto de candidatos na fase de filtragem, o benefício do desempenho pode ser limitado. Nesses casos, a execução da consulta ainda pode se aproximar do custo de uma varredura completa, mesmo que o índice esteja presente.
Avaliação do desempenho do índice Ngram em consultas LIKE
O objetivo deste parâmetro de comparação é avaliar a eficácia com que o índice Ngram acelera as consultas LIKE na prática.
Metodologia de teste
Para colocar seu desempenho em contexto, comparamos com dois modos de execução de linha de base:
Mestre: Execução de força bruta sem nenhum índice.
Mestre-invertido: Execução usando um índice invertido convencional.
Concebemos dois cenários de teste para cobrir diferentes caraterísticas dos dados:
Conjunto de dados de texto Wiki: 100.000 linhas, com cada campo de texto truncado a 1 KB.
Conjunto de dados de uma só palavra: 1.000.000 linhas, em que cada linha contém uma única palavra.
Em ambos os cenários, as seguintes definições são aplicadas de forma consistente:
As consultas usam o padrão de correspondência infixa (
%xxx%)O índice Ngram é configurado com
min_gram = 2emax_gram = 4Para isolar o custo de execução da consulta e evitar a sobrecarga de materialização de resultados, todas as consultas retornam
count(*)em vez de conjuntos completos de resultados.
Resultados
Teste para wiki, cada linha é um texto wiki com comprimento de conteúdo truncado por 1000, 100K linhas
| Literal | Tempo (ms) | Aceleração | Contagem | |
|---|---|---|---|---|
| Mestre | Estádio | 207.8 | 335 | |
| Mestre-invertido | 2095 | 335 | ||
| Ngrama | 1.09 | 190 / 1922 | 335 | |
| Mestre | escola secundária | 204.8 | 340 | |
| Mestre-invertido | 2000 | 340 | ||
| Ngrama | 1.26 | 162.5 / 1587 | 340 | |
| Mestre | é um estabelecimento de ensino secundário coeducacional | 223.9 | 1 | |
| Mestre-invertido | 2100 | 1 | ||
| Ngrama | 1.69 | 132.5 / 1242.6 | 1 |
Teste para palavras individuais, 1M linhas
| Literal | Tempo (ms) | Aceleração | Contagem | |
|---|---|---|---|---|
| Mestre | na | 128.6 | 40430 | |
| Mestre-invertido | 66.5 | 40430 | ||
| Ngrama | 1.38 | 93.2 / 48.2 | 40430 | |
| Mestre | nat | 122 | 5200 | |
| Mestre-invertido | 65.1 | 5200 | ||
| Ngrama | 1.27 | 96 / 51.3 | 5200 | |
| Mestre | nati | 118.8 | 1630 | |
| Mestre-invertido | 66.9 | 1630 | ||
| Ngrama | 1.21 | 98.2 / 55.3 | 1630 | |
| Mestre | natio | 118.4 | 1100 | |
| Mestre-invertido | 65.1 | 1100 | ||
| Ngrama | 1.33 | 89 / 48.9 | 1100 | |
| Mestre | nação | 118 | 1100 | |
| Mestre-invertido | 63.3 | 1100 | ||
| Ngrama | 1.4 | 84.3 / 45.2 | 1100 |
Nota: Estes resultados são baseados em benchmarks realizados em maio. Desde então, o ramo Master foi submetido a optimizações de desempenho adicionais, pelo que se espera que a diferença de desempenho aqui observada seja menor nas versões actuais.
Os resultados do benchmark destacam um padrão claro: o Índice de Ngramas acelera significativamente as consultas LIKE em todos os casos, e a rapidez com que as consultas são executadas depende fortemente da estrutura e do comprimento dos dados de texto subjacentes.
Para campos de texto longos, como documentos do tipo Wiki truncados em 1.000 bytes, os ganhos de desempenho são especialmente pronunciados. Em comparação com a execução de força bruta sem índice, o índice Ngram atinge aumentos de velocidade de cerca de 100-200×. Quando comparado com um índice invertido convencional, a melhoria é ainda mais dramática, atingindo 1.200-1.900×. Isto deve-se ao facto de as consultas LIKE em textos longos serem particularmente dispendiosas para as abordagens de indexação tradicionais, enquanto as pesquisas de n-gramas podem reduzir rapidamente o espaço de pesquisa a um conjunto muito pequeno de candidatos.
Em conjuntos de dados constituídos por entradas de uma só palavra, os ganhos são menores, mas ainda assim substanciais. Neste cenário, o Índice Ngram é aproximadamente 80-100× mais rápido do que a execução de força bruta e 45-55× mais rápido do que um índice invertido convencional. Embora um texto mais curto seja inerentemente mais barato de digitalizar, a abordagem baseada em n-gramas continua a evitar comparações desnecessárias e reduz consistentemente o custo da consulta.
Conclusão
O índice Ngram acelera as consultas LIKE dividindo o texto em n-gramas de comprimento fixo e indexando-os usando uma estrutura invertida. Esta conceção transforma a dispendiosa correspondência de substracções em pesquisas eficientes de n-gramas, seguidas de uma verificação mínima. Como resultado, evitam-se as pesquisas em todo o texto e preserva-se a semântica exacta de LIKE.
Na prática, esta abordagem é eficaz numa vasta gama de cargas de trabalho, com resultados especialmente fortes para a correspondência difusa em campos de texto longos. Por conseguinte, o índice Ngram é adequado para cenários em tempo real, como a pesquisa de códigos, agentes de apoio ao cliente, recuperação de documentos jurídicos e médicos, bases de conhecimentos empresariais e pesquisa académica, em que a correspondência precisa de palavras-chave continua a ser essencial.
Ao mesmo tempo, o Ngram Index beneficia de uma configuração cuidadosa. A escolha de valores apropriados em min_gram e max_gram é fundamental para equilibrar o tamanho do índice e o desempenho da consulta. Quando ajustado para refletir padrões de consulta reais, o Índice de Ngramas fornece uma solução prática e escalável para consultas LIKE de elevado desempenho em sistemas de produção.
Para obter mais informações sobre o Índice Ngram, consulte a documentação abaixo:
Tem dúvidas ou quer um mergulho profundo em qualquer recurso do Milvus mais recente? Junte-se ao nosso canal Discord ou arquive problemas no GitHub. Você também pode reservar uma sessão individual de 20 minutos para obter insights, orientações e respostas às suas perguntas através do Milvus Office Hours.
Saiba mais sobre os recursos do Milvus 2.6
Apresentando o Milvus 2.6: Pesquisa Vetorial Acessível à Escala de Bilhões
Apresentando a função Embedding: Como o Milvus 2.6 agiliza a vetorização e a busca semântica
JSON Shredding no Milvus: Filtragem JSON 88,9x mais rápida com flexibilidade
Filtragem Geoespacial e Pesquisa Vetorial com Campos Geométricos e RTREE no Milvus 2.6
MinHash LSH em Milvus: a arma secreta para combater duplicatas em dados de treinamento LLM
Leve a compressão vetorial ao extremo: como o Milvus atende a 3× mais consultas com o RaBitQ
Os benchmarks mentem - os bancos de dados vetoriais merecem um teste real
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



