NGRAM
El índice NGRAM en Milvus se construye para acelerar las consultas LIKE en campos VARCHAR o rutas JSON específicas dentro de campos JSON. Antes de construir el índice, Milvus divide el texto en subcadenas cortas y superpuestas de una longitud fija n, conocidas como n-gramas. Por ejemplo, con n = 3, la palabra "Milvus" se divide en 3gramas: "Mil", "ilv", "lvu" y "vus". Estos n-gramas se almacenan en un índice invertido que relaciona cada gramo con el ID del documento en el que aparece. En el momento de la consulta, este índice permite a Milvus limitar rápidamente la búsqueda a un pequeño conjunto de candidatos, lo que se traduce en una ejecución mucho más rápida de la consulta.
Utilícelo cuando necesite un filtrado rápido mediante prefijos, sufijos, infijos o comodines, por ejemplo:
name LIKE "data%"title LIKE "%vector%"path LIKE "%json"
Para más detalles sobre la sintaxis de las expresiones de filtrado, consulte Operadores básicos.
Cómo funciona
Milvus implementa el índice NGRAM en un proceso de dos fases:
Construir el índice: Genera n-gramas para cada documento y construye un índice invertido durante la ingesta.
Acelerar las consultas: Utiliza el índice para filtrar un pequeño conjunto de candidatos y, a continuación, verifica las coincidencias exactas.
Fase 1: Construir el índice
Durante la ingesta de datos, Milvus construye el índice NGRAM realizando dos pasos principales:
Descomponer el texto en n-gramas: Milvus desliza una ventana de n por cada cadena del campo de destino y extrae las subcadenas superpuestas, o n-gramas. La longitud de estas subcadenas cae dentro de un rango configurable,
[min_gram, max_gram].min_gram: El n-grama más corto a generar. Esto también define la longitud mínima de la subcadena de consulta que puede beneficiarse del índice.max_gram: El n-grama más largo a generar. En el momento de la consulta, también se utiliza como tamaño máximo de ventana al dividir cadenas de consulta largas.
Por ejemplo, con
min_gram=2ymax_gram=3, la cadena"AI database"se divide de la siguiente manera:
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 un índice invertido: Se crea un índice invertido que asigna cada n-grama generado a una lista de los ID de documentos que lo contienen.
Por ejemplo, si el n-grama
"AI"aparece en documentos con ID 1, 5, 6, 8 y 9, el índice registra{"AI": [1, 5, 6, 8, 9]}. Este índice se utiliza en el momento de la consulta para limitar rápidamente el ámbito de la búsqueda.
Creación del í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 las consultas
Cuando se ejecuta un filtro LIKE, Milvus utiliza el índice NGRAM para acelerar la consulta en los siguientes pasos:
Acelerar consultas
Extraer el término de la consulta: La subcadena contigua sin comodines se extrae de la expresión
LIKE(por ejemplo,"%database%"se convierte en"database").Descomponer el término de la consulta: El término de la consulta se descompone en n-gramas en función de su longitud (
L) y de los índicesmin_gramymax_gram.Si
L < min_gram, el índice no puede utilizarse y la consulta vuelve a una búsqueda completa.Si
min_gram ≤ L ≤ max_gram, todo el término de la consulta se trata como un único n-grama y no es necesaria ninguna otra descomposición.Si
L > max_gram, el término de la consulta se descompone en gramos superpuestos utilizando un tamaño de ventana igual amax_gram.
Por ejemplo, si
max_gramse fija en3y el término de la consulta es"database", que tiene una longitud de 8, se descompone en subcadenas de 3 gramos como"dat","ata","tab", etc.Buscar cada gramo e intersecar: Milvus busca cada uno de los gramos de la consulta en el índice invertido y luego interseca las listas de ID de documentos resultantes para encontrar un pequeño conjunto de documentos candidatos. Estos candidatos contienen todos los gramos de la consulta.
Verifica y devuelve los resultados: El filtro original
LIKEse aplica entonces como comprobación final sólo en el pequeño conjunto de candidatos para encontrar las coincidencias exactas.
Crear un índice NGRAM
Puede crear un índice NGRAM en un campo VARCHAR o en una ruta específica dentro de un campo JSON.
Ejemplo 1: Creación en un campo VARCHAR
Para un campo VARCHAR, basta con especificar el field_name y configurar min_gram y 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 configuración genera 2-gramas y 3-gramas para cada cadena en text y los almacena en el índice invertido.
Ejemplo 2: Creación en una ruta JSON
Para un campo JSON, además de la configuración de gramos, también debe especificar
params.json_path- la ruta JSON que apunta al valor que desea indexar.params.json_cast_type- debe ser"varchar"(no distingue mayúsculas de minúsculas), porque la indexación NGRAM opera sobre cadenas.
# 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
)
En este ejemplo:
Sólo se indexa el valor en
json_field["body"].El valor se convierte a
VARCHARantes de la tokenización n-gram.Milvus genera subcadenas de longitud 2 a 4 y las almacena en el índice invertido.
Para más información sobre cómo indexar un campo JSON, consulte Indexación JSON.
Consultas aceleradas por NGRAM
Para que se aplique el índice NGRAM:
La consulta debe dirigirse a un campo
VARCHAR(o ruta JSON) que tenga un índiceNGRAM.La parte literal del patrón
LIKEdebe tener al menosmin_gramcaracteres.(Por ejemplo, si el término de consulta más corto que espera es de 2 caracteres, establezca min_gram=2 al crear el índice).
Tipos de consulta admitidos:
Coincidencia de prefijo
# Match any string that starts with the substring "database" filter = 'text LIKE "database%"'Coincidencia de sufijo
# Match any string that ends with the substring "database" filter = 'text LIKE "%database"'Coincidencia infija
# Match any string that contains the substring "database" anywhere filter = 'text LIKE "%database%"'Coincidencia con comodín
Milvus admite tanto
%(cero o más caracteres) como_(exactamente un carácter).# Match any string where "st" appears first, and "um" appears later in the text filter = 'text LIKE "%st%um%"'Consultas de rutas JSON
filter = 'json_field["body"] LIKE "%database%"'
Para más información sobre la sintaxis de las expresiones de filtrado, consulte Operadores básicos.
Eliminar un índice
Utilice el método drop_index() para eliminar un índice existente de una colección.
client.drop_index(
collection_name="Documents", # Name of the collection
index_name="ngram_index" # Name of the index to drop
)
Notas de uso
Tipos de campo: Compatible con los campos
VARCHARyJSON. Para JSON, proporcione tantoparams.json_pathcomoparams.json_cast_type="varchar".Unicode: La descomposición NGRAM se basa en caracteres y es independiente del idioma, e incluye los espacios en blanco y la puntuación.
Compromiso espacio-tiempo: los rangos de gramos más amplios
[min_gram, max_gram]producen más gramos e índices más grandes. Si la memoria es escasa, considere el modommappara listas de contabilización grandes. Para más información, consulte Uso de mmap.Inmutabilidad:
min_gramymax_gramno se pueden cambiar in situ: reconstruya el índice para ajustarlos.
Buenas prácticas
Elija min_gram y max_gram para que coincidan con el comportamiento de búsqueda
Empezar con
min_gram=2,max_gram=3.Establezca
min_gramen el literal más corto que espera que escriban los usuarios.Establezca
max_gramcerca de la longitud típica de las subcadenas significativas; unmax_grammayor mejora el filtrado pero aumenta el espacio.
Evite los gramos de baja selectividad
Los patrones muy repetitivos (por ejemplo,
"aaaaaa") proporcionan un filtrado débil y pueden aportar beneficios limitados.Normalización coherente
Aplique la misma normalización al texto ingestado y a los literales de consulta (por ejemplo, minúsculas, recorte) si su caso de uso lo requiere.