NGRAM
O índice NGRAM no Milvus foi criado para acelerar as consultas LIKE em campos VARCHAR ou caminhos JSON específicos dentro de campos JSON. Antes de construir o índice, o Milvus divide o texto em substrings curtas e sobrepostas de um comprimento fixo n, conhecidas como n-gramas. Por exemplo, com n = 3, a palavra "Milvus" é dividida em 3 gramas: "Mil", "ilv", "lvu" e "vus". Estes n-gramas são então armazenados num índice invertido que mapeia cada grama para os IDs dos documentos em que aparece. No momento da consulta, este índice permite ao Milvus restringir rapidamente a pesquisa a um pequeno conjunto de candidatos, resultando numa execução muito mais rápida da consulta.
Utilize-o quando necessitar de uma filtragem rápida de prefixos, sufixos, infixos ou wildcards, tais como:
name LIKE "data%"title LIKE "%vector%"path LIKE "%json"
Para obter detalhes sobre a sintaxe da expressão de filtro, consulte Operadores básicos.
Como funciona
O Milvus implementa o índice NGRAM num processo de duas fases:
Construir o índice: Gerar n-gramas para cada documento e construir um índice invertido durante a ingestão.
Acelerar as consultas: Utilizar o índice para filtrar um pequeno conjunto de candidatos e, em seguida, verificar as correspondências exactas.
Fase 1: Construir o índice
Durante a ingestão de dados, o Milvus constrói o índice NGRAM executando duas etapas principais:
Decompor o texto em n-gramas: O Milvus desliza uma janela de n por cada string no campo de destino e extrai substrings sobrepostas, ou n-gramas. O comprimento dessas substrings está dentro de um intervalo configurável,
[min_gram, max_gram].min_gram: O n-grama mais curto a ser gerado. Isso também define o comprimento mínimo da substring da consulta que pode se beneficiar do índice.max_gram: O n-grama mais longo a ser gerado. No momento da consulta, também é utilizado como o tamanho máximo da janela ao dividir cadeias de consulta longas.
Por exemplo, com
min_gram=2emax_gram=3, a cadeia"AI database"é dividida da seguinte forma:
Construir índice Ngram
- **2-grams:** `AI`, `I_`, `_d`, `da`, `at`, ...
- **3-grams:** `AI_`, `I_d`, `_da`, `dat`, `ata`, ...
<div class="alert note">
- For a range `[min_gram, max_gram]`, Milvus generates all n-grams for every length between the two values (inclusive). For example, with `[2,4]` and the word `"text"`, Milvus generates:
- **2-grams:** `te`, `ex`, `xt`
- **3-grams:** `tex`, `ext`
- **4-grams:** `text`
- N-gram decomposition is character-based and language-agnostic. For example, in Chinese, `"向量数据库"` with `min_gram = 2` is decomposed into: `"向量"`, `"量数"`, `"数据"`, `"据库"`.
- Spaces and punctuation are treated as characters during decomposition.
- Decomposition preserves original case, and matching is case-sensitive. For example, `"Database"` and `"database"` will generate different n-grams and require exact case matching during queries.
</div>
Construir um índice invertido: É criado um índice invertido que mapeia cada n-grama gerado para uma lista dos IDs de documentos que o contêm.
Por exemplo, se o 2-grama
"AI"aparecer em documentos com IDs 1, 5, 6, 8 e 9, o índice regista{"AI": [1, 5, 6, 8, 9]}. Este índice é então utilizado no momento da consulta para restringir rapidamente o âmbito da pesquisa.
Construir o índice de ngramas 2
<div class="alert note">
A wider `[min_gram, max_gram]` range creates more grams and larger mapping lists. If memory is tight, consider mmap mode for very large posting lists. For details, refer to [Use mmap](https://zilliverse.feishu.cn/wiki/P3wrwSMNNihy8Vkf9p6cTsWYnTb).
</div>
Fase 2: Acelerar as consultas
Quando um filtro LIKE é executado, o Milvus utiliza o índice NGRAM para acelerar a consulta nos seguintes passos:
Acelerar consultas
Extrair o termo da consulta: A substring contígua sem wildcards é extraída da expressão
LIKE(por exemplo,"%database%"torna-se"database").Decompor o termo de consulta: O termo de consulta é decomposto em n-gramas com base no seu comprimento (
L) e nas definiçõesmin_gramemax_gram.Se
L < min_gram, o índice não pode ser utilizado e a consulta regressa a uma pesquisa completa.Se
min_gram ≤ L ≤ max_gram, todo o termo da consulta é tratado como um único n-grama e não é necessária mais decomposição.Se
L > max_gram, o termo da consulta é decomposto em gramas sobrepostos utilizando um tamanho de janela igual amax_gram.
Por exemplo, se
max_gramestiver definido como3e o termo consultado for"database", que tem um comprimento de 8, é decomposto em substrings de 3 gramas como"dat","ata","tab", e assim por diante.Procurar cada grama e intersectar: O Milvus procura cada uma das gramas da consulta no índice invertido e, em seguida, intersecta as listas de ID dos documentos resultantes para encontrar um pequeno conjunto de documentos candidatos. Estes candidatos contêm todas as gramas da consulta.
Verificar e devolver os resultados: O filtro original
LIKEé então aplicado como verificação final apenas no pequeno conjunto de candidatos para encontrar as correspondências exactas.
Criar um índice NGRAM
Pode criar um índice NGRAM num campo VARCHAR ou num caminho específico dentro de um campo JSON.
Exemplo 1: Criar num campo VARCHAR
Para um campo VARCHAR, basta especificar o field_name e configurar min_gram e max_gram.
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530") # Replace with your server address
# Assume you have defined a VARCHAR field named "text" in your collection schema
# Prepare index parameters
index_params = client.prepare_index_params()
# Add NGRAM index on the "text" field
index_params.add_index(
field_name="text", # Target VARCHAR field
index_type="NGRAM", # Index type is NGRAM
index_name="ngram_index", # Custom name for the index
min_gram=2, # Minimum substring length (e.g., 2-gram: "st")
max_gram=3 # Maximum substring length (e.g., 3-gram: "sta")
)
# Create the index on the collection
client.create_index(
collection_name="Documents",
index_params=index_params
)
Esta configuração gera 2-gramas e 3-gramas para cada cadeia de caracteres em text e armazena-os no índice invertido.
Exemplo 2: Criar num caminho JSON
Para um campo JSON, para além das definições de grama, também tem de especificar:
params.json_path- o caminho JSON que aponta para o valor que você deseja indexar.params.json_cast_type- deve ser"varchar"(não diferencia maiúsculas de minúsculas), porque a indexação NGRAM opera em strings.
# Assume you have defined a JSON field named "json_field" in your collection schema, with a JSON path named "body"
# Prepare index parameters
index_params = client.prepare_index_params()
# Add NGRAM index on a JSON field
index_params.add_index(
field_name="json_field", # Target JSON field
index_type="NGRAM", # Index type is NGRAM
index_name="json_ngram_index", # Custom index name
min_gram=2, # Minimum n-gram length
max_gram=4, # Maximum n-gram length
params={
"json_path": "json_field[\"body\"]", # Path to the value inside the JSON field
"json_cast_type": "varchar" # Required: cast the value to varchar
}
)
# Create the index on the collection
client.create_index(
collection_name="Documents",
index_params=index_params
)
Neste exemplo:
Apenas o valor em
json_field["body"]é indexado.O valor é convertido para
VARCHARantes da tokenização do n-grama.Milvus gera substrings de comprimento 2 a 4 e armazena-os no índice invertido.
Para obter mais informações sobre como indexar um campo JSON, consulte Indexação JSON.
Consultas aceleradas por NGRAM
Para que o índice NGRAM seja aplicado:
A consulta deve ter como alvo um campo
VARCHAR(ou caminho JSON) que tenha um índiceNGRAM.A parte literal do padrão
LIKEdeve ter pelo menosmin_gramcaracteres de comprimento.(Por exemplo, se o termo de consulta mais curto esperado for 2 caracteres, defina min_gram=2 ao criar o índice).
Tipos de consulta suportados:
Correspondência de prefixo
# Match any string that starts with the substring "database" filter = 'text LIKE "database%"'Correspondência de sufixo
# Match any string that ends with the substring "database" filter = 'text LIKE "%database"'Correspondência de infixo
# Match any string that contains the substring "database" anywhere filter = 'text LIKE "%database%"'Correspondência com curinga
O Milvus suporta tanto
%(zero ou mais caracteres) como_(exatamente um carácter).# Match any string where "st" appears first, and "um" appears later in the text filter = 'text LIKE "%st%um%"'Consultas de caminho JSON
filter = 'json_field["body"] LIKE "%database%"'
Para obter mais informações sobre a sintaxe da expressão de filtro, consulte Operadores básicos.
Eliminar um índice
Utilize o método drop_index() para remover um índice existente de uma coleção.
client.drop_index(
collection_name="Documents", # Name of the collection
index_name="ngram_index" # Name of the index to drop
)
Notas de utilização
Tipos de campo: Suportado nos campos
VARCHAReJSON. Para JSON, forneçaparams.json_patheparams.json_cast_type="varchar".Unicode: A decomposição NGRAM é baseada em caracteres e independente da língua e inclui espaços em branco e pontuação.
Compensação espaço-tempo: intervalos de gramas mais amplos
[min_gram, max_gram]produzem mais gramas e índices maiores. Se a memória for escassa, considere o modommappara listas de lançamento grandes. Para mais informações, consulte Use mmap.Imutabilidade:
min_gramemax_gramnão podem ser alterados no local - reconstrua o índice para os ajustar.
Melhores práticas
Escolha min_gram e max_gram para corresponder ao comportamento de pesquisa
Comece com
min_gram=2,max_gram=3.Defina
min_gramcomo o literal mais curto que espera que os utilizadores escrevam.Defina
max_grampróximo do comprimento típico das substrings significativas; ummax_grammaior melhora a filtragem, mas aumenta o espaço.
Evitar gramas de baixa seletividade
Padrões altamente repetitivos (por exemplo,
"aaaaaa") fornecem filtragem fraca e podem produzir ganhos limitados.Normalize de forma consistente
Aplique a mesma normalização ao texto ingerido e aos literais da consulta (por exemplo, minúsculas, corte) se o seu caso de uso precisar disso.