• Acerca de Milvus
  • Comenzar
  • Conceptos
  • Guía del usuario
  • Importación de datos
  • Herramientas de IA
  • Guía de administración
  • Herramientas
  • Integraciones
  • Tutoriales
  • Preguntas frecuentes
  • API Reference

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:

  1. Construir el índice: Genera n-gramas para cada documento y construye un índice invertido durante la ingesta.

  2. 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:

  1. 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=2 y max_gram=3, la cadena "AI database" se divide de la siguiente manera:

Build Ngram Index 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>
  1. 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.

Build Ngram Index 2 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:

Accelerate Queries Acelerar consultas

  1. 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").

  2. 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 índices min_gram y max_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 a max_gram.

    Por ejemplo, si max_gram se fija en 3 y 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.

  3. 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.

  4. Verifica y devuelve los resultados: El filtro original LIKE se 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 VARCHAR antes 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 índice NGRAM.

  • La parte literal del patrón LIKE debe tener al menos min_gram caracteres.(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 VARCHAR y JSON. Para JSON, proporcione tanto params.json_path como params.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 modo mmap para listas de contabilización grandes. Para más información, consulte Uso de mmap.

  • Inmutabilidad: min_gram y max_gram no 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_gram en el literal más corto que espera que escriban los usuarios.

    • Establezca max_gram cerca de la longitud típica de las subcadenas significativas; un max_gram mayor 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.