Indexación de JSON
Los campos JSON ofrecen una forma flexible de almacenar metadatos estructurados en Milvus. Sin indexación, las consultas en campos JSON requieren escaneos completos de la colección, lo que ralentiza el proceso a medida que crece el conjunto de datos. La indexación JSON crea un índice en una ruta específica dentro de los datos JSON, de modo que las consultas de igualdad, rango y otros filtros en esa ruta se ejecutan rápidamente.
La indexación JSON es ideal para:
Esquemas estructurados con claves conocidas y consistentes
Consultas de igualdad, «
IN», de rango y de coincidencia de texto en rutas JSON específicasEscenarios en los que se necesita un control preciso sobre qué claves se indexan
Para documentos JSON complejos con patrones de consulta diversos, plantéate utilizar el «JSON Shredding» como alternativa.
Descripción general de los tipos de índice
Milvus ofrece cuatro tipos de índice para rutas JSON. Cada uno de ellos se adapta a un patrón de consulta diferente.
Antes de elegir un tipo de índice, identifica el tipo de conversión de la ruta JSON. El tipo de conversión determina cómo interpreta Milvus el valor en esa ruta y qué tipos de índice están disponibles.
Comprender los tipos de conversión
json_cast_type es el tipo de datos que se utiliza para interpretar e indexar el valor en json_path. Es diferente del tipo de esquema del campo: el campo sigue siendo un campo « JSON », pero cada ruta indexada se trata como un tipo específico de escalar, matriz u objeto JSON.
Elija el tipo de conversión que se ajuste a los valores almacenados en la ruta. Para comprobar si un tipo de conversión es compatible con un tipo de índice específico, consulte la Referencia de compatibilidad.
| Tipo de conversión | Úsalo cuando el valor de la ruta sea… | Valor de ejemplo |
|---|---|---|
BOOL | Un valor booleano | true |
DOUBLE | Un valor numérico | 99.99 |
VARCHAR | Un valor de cadena | "electronics" |
ARRAY_BOOL | Una matriz de valores booleanos | [true, false] |
ARRAY_DOUBLE | Un array de valores numéricos | [1.2, 3.14] |
ARRAY_VARCHAR | Un array de valores de cadena | ["tag1", "tag2"] |
JSON | Un objeto JSON completo o un subobjeto. La indexación de objetos JSON completos ha quedado obsoleta a partir de Milvus 3.0.0. | {"supplier": {"country": "USA"}} |
Si los valores de una misma ruta tienen tipos incompatibles, solo se indexan los valores que coinciden con el tipo de conversión. Por ejemplo, si metadata["price"] contiene tanto 99.99 como "99.99", un índice del tipo de conversión DOUBLE incluirá el valor numérico y omitirá el valor de cadena. Para convertir valores de cadena durante la indexación, utiliza json_cast_function; consulta el Ejemplo 5: Convertir el tipo de datos en el momento de la indexación.
Elige un tipo de índice
Una vez elegido el tipo de conversión, elija el tipo de índice según su patrón de consulta.
| Patrón de consulta | Tipo de índice recomendado | Requisitos del tipo de conversión | Notas |
|---|---|---|---|
| Filtros mixtos de igualdad y de rango sobre valores escalares | AUTOINDEX | Utilice « BOOL », « DOUBLE » o « VARCHAR ». | Permite que Milvus elija la estructura interna del índice en función de la cardinalidad de los valores. |
| Filtros sobre valores dentro de matrices JSON | INVERTED | Utilice ARRAY_BOOL, ARRAY_DOUBLE o ARRAY_VARCHAR. | Obligatorio para todos los tipos de conversión de matrices. |
| Indexación de objetos completos o subobjetos (obsoleto) | INVERTED o AUTOINDEX (solo por compatibilidad) | Utilice JSON. | Compatible por motivos de compatibilidad. Para nuevas cargas de trabajo, cree índices específicos de ruta o considere el uso de JSON Shredding. |
| Filtros de rango sobre números o cadenas ordenables | STL_SORT o AUTOINDEX | Utilice DOUBLE o VARCHAR. | Utilice STL_SORT para forzar un diseño ordenado; utilice AUTOINDEX cuando desee una selección automática. |
Filtros de igualdad o de « IN » en valores de baja cardinalidad | BITMAP o AUTOINDEX | Utilice BOOL o VARCHAR. | Utiliza « BITMAP » para forzar una disposición de mapa de bits. Para valores numéricos, utiliza « AUTOINDEX » o « STL_SORT ». |
En caso de duda, empieza con AUTOINDEX para rutas escalares. Utiliza INVERTED de forma explícita para tipos de conversión de matriz y consultas de coincidencia de texto. La indexación JSON de objetos completos con INVERTED o AUTOINDEX sigue siendo compatible, pero queda obsoleta a partir de Milvus 3.0.0.
AUTOINDEX
AUTOINDEX depende del « json_cast_type » que se especifique. En Milvus 3.0, « AUTOINDEX » ya no se resuelve siempre como « INVERTED » para los índices de ruta JSON.
| Comportamiento de la conversión de tipo | AUTOINDEX comportamiento |
|---|---|
BOOL, DOUBLE, VARCHAR | Elige entre BITMAP y STL_SORT en función de la cardinalidad del valor. |
ARRAY_BOOL, ARRAY_DOUBLE, ARRAY_VARCHAR | No es compatible. Utiliza « INVERTED » explícitamente como tipo de índice. |
JSON | Utiliza INVERTED para la indexación de objetos completos o subobjetos. Este modo queda obsoleto a partir de Milvus 3.0.0. |
Para los tipos de conversión escalar (BOOL, DOUBLE y VARCHAR), AUTOINDEX es el punto de partida recomendado cuando se desea que Milvus elija la estructura interna del índice. Durante la creación del índice, Milvus mide la cardinalidad de los valores en la ruta JSON. La cardinalidad se refiere al número de valores distintos en esa ruta.
En función de la cardinalidad, Milvus elige una de estas dos estructuras internas:
Baja cardinalidad: los valores se repiten con frecuencia, como
metadata["in_stock"]junto contrueyfalse, ometadata["status"]con un pequeño conjunto de cadenas de estado. Milvus crea internamente un índice de tipo «BITMAP» para agilizar los filtros de igualdad y de «IN».Alta cardinalidad: la mayoría de los valores son distintos, como
metadata["price"],metadata["created_at"]ometadata["product_id"]. Milvus crea internamente un índiceSTL_SORTpara filtros de rango rápidos, como>,<,>=y<=.
El umbral predeterminado de « BITMAP » frente a «STL_SORT » es de 100 valores distintos. Puedes ajustar este umbral con « bitmap_cardinality_limit »; consulta «¿Cómo ajusto el umbral de BITMAP frente a STL_SORT de AUTOINDEX?».
Cambio de comportamiento en Milvus 3.0. En versiones anteriores, AUTOINDEX en rutas JSON siempre creaba un índice INVERTED. A partir de Milvus 3.0, AUTOINDEX elige entre BITMAP y STL_SORT para los tipos de conversión escalares. Para JSON, AUTOINDEX sigue utilizando INVERTED, aunque la indexación JSON de objetos completos está en desuso. Para los tipos de conversión de matriz y las consultas de coincidencia de texto, especifica INVERTED de forma explícita.
INVERTED
INVERTED es la opción más adecuada cuando se necesitan consultas de coincidencia de texto o indexación de matrices. También sigue estando disponible para la indexación de objetos JSON completos, que ha quedado obsoleta.
Especifica INVERTED de forma explícita cuando:
Necesites indexar valores dentro de matrices JSON.
Mantenga un índice existente sobre un objeto JSON completo o un subobjeto y desee hacer explícito el comportamiento de «
INVERTED».Desea un único tipo de índice que gestione consultas de igualdad, «
IN», de rango, de coincidencia de texto y de matriz. La compatibilidad con objetos completos sigue estando disponible por motivos de compatibilidad, a costa de un mayor tamaño del índice.
Para los índices existentes sobre objetos JSON completos (json_cast_type="JSON"), puede seguir utilizando INVERTED o AUTOINDEX. AUTOINDEX utiliza INVERTED para este tipo de conversión. Ya no se recomienda la indexación de objetos JSON completos para nuevas cargas de trabajo.
Para obtener más información, consulta INVERTED.
STL_SORT
STL_SORT almacena los valores de una ruta JSON en orden clasificado. Está optimizado para filtros de rango sobre valores numéricos o valores de cadena clasificables.
STL_SORT Solo admite los tipos de conversión DOUBLE y VARCHAR. Úsalo cuando:
Sus filtros comparen valores con
>,<,>=o<=.Los valores indexados tengan una cardinalidad elevada, como precios, marcas de tiempo, identificadores o códigos ordenables.
Deseas forzar un diseño ordenado en lugar de dejar que
AUTOINDEXelija.
STL_SORT No admite los tipos de conversión BOOL, ARRAY_* ni JSON. Utiliza INVERTED para las matrices. Los índices de objetos completos existentes pueden seguir utilizando INVERTED o AUTOINDEX, pero la indexación JSON de objetos completos está en desuso.
Para más detalles, consulte STL_SORT.
BITMAP
BITMAP crea un mapa de bits compacto para cada valor distinto en una ruta JSON. Está optimizado para filtros de igualdad y de « IN » en valores que se repiten con frecuencia.
BITMAP Solo admite los tipos de conversión « BOOL » y « VARCHAR ». Úsalo cuando:
Sus filtros utilicen «
==» o «IN».Los valores indexados tengan una cardinalidad baja, como valores booleanos, valores de estado o un conjunto reducido de categorías.
Desees forzar un diseño de mapa de bits en lugar de dejar que
AUTOINDEXelija.
BITMAP No admite los tipos de conversión « DOUBLE », « ARRAY_* » ni « JSON ». Para valores numéricos, utilice en su lugar « AUTOINDEX », « STL_SORT » o « INVERTED ».
Para obtener más información, consulte BITMAP.
Referencia de compatibilidad
Utilice la siguiente matriz como referencia rápida para las combinaciones de « (cast type, index type) » compatibles.
| Tipo de conversión | Descripción | Valor de ejemplo | AUTOINDEX | INVERTIDO | STL_SORT | BITMAP |
|---|---|---|---|---|---|---|
BOOL | Valores booleanos (true/false). | true | Sí | Sí | No | Sí |
DOUBLE | Valores numéricos (enteros o decimales). | 99.99 | Sí | Sí | Sí | No |
VARCHAR | Valores de cadena. | "electronics" | Sí | Sí | Sí | Sí |
ARRAY_BOOL | Matriz de valores booleanos. | [true, false] | No | Sí | No | No |
ARRAY_DOUBLE | Matriz de números. | [1.2, 3.14] | No | Sí | No | No |
ARRAY_VARCHAR | Matriz de cadenas. | ["tag1", "tag2"] | No | Sí | No | No |
JSON | Un objeto JSON completo o un subobjeto con inferencia automática de tipos y aplanamiento. Obsoleto a partir de Milvus 3.0.0. | cualquier objeto anidado | Sí (obsoleto) | Sí (obsoleto) | No | No |
En el caso de las celdas marcadas como « No », Milvus rechaza la solicitud en el momento de la creación del índice. Para los tipos de conversión de matrices, utiliza explícitamente « INVERTED » (AUTOINDEX no cubre las matrices).
Crear un índice JSON
En esta sección se explica cómo indexar datos JSON con diferentes estructuras. Todos los ejemplos utilizan la estructura de muestra que se muestra a continuación y dan por hecho que ya dispone de una colección que incluye un campo « JSON » denominado « metadata ».
Estructura JSON de ejemplo
{
"metadata": {
"category": "electronics",
"brand": "BrandA",
"in_stock": true,
"price": 99.99,
"string_price": "99.99",
"tags": ["clearance", "summer_sale"],
"supplier": {
"name": "SupplierX",
"country": "USA",
"contact": {
"email": "support@supplierx.com",
"phone": "+1-800-555-0199"
}
}
}
}
Configuración básica
Los ejemplos siguientes dan por hecho que dispone de un « MilvusClient » denominado « client » conectado a su implementación de Milvus, y de una colección que ya incluye un campo « JSON » denominado « metadata ». Si necesita configurarlos desde cero, expanda el bloque siguiente.
from pymilvus import DataType, MilvusClient
client = MilvusClient(uri="http://localhost:19530")
# Define a schema with a JSON field
schema = client.create_schema(enable_dynamic_field=False)
schema.add_field("pk", DataType.INT64, is_primary=True, auto_id=False)
schema.add_field("vec", DataType.FLOAT_VECTOR, dim=4)
schema.add_field("metadata", DataType.JSON, nullable=True)
# Minimal vector index so the collection can be loaded
vec_index = client.prepare_index_params()
vec_index.add_index(field_name="vec", index_type="AUTOINDEX", metric_type="L2")
client.create_collection(
collection_name="your_collection_name",
schema=schema,
index_params=vec_index,
)
# Insert one row that matches the sample JSON structure above
client.insert(
collection_name="your_collection_name",
data=[{
"pk": 1,
"vec": [0.1, 0.2, 0.3, 0.4],
"metadata": {
"category": "electronics",
"brand": "BrandA",
"in_stock": True,
"price": 99.99,
"string_price": "99.99",
"tags": ["clearance", "summer_sale"],
"supplier": {
"name": "SupplierX",
"country": "USA",
"contact": {
"email": "support@supplierx.com",
"phone": "+1-800-555-0199"
}
}
}
}],
)
Prepara un objeto `index-params` para recopilar las definiciones de índice añadidas en los ejemplos siguientes:
index_params = client.prepare_index_params()
Cada uno de los ejemplos siguientes muestra una llamada a ` index_params.add_index(...) `. Elige los que se ajusten a tus datos y llámalos en el mismo objeto ` index_params `. A continuación, aplica todo en una única llamada a ` client.create_index(...) ` al final. Para obtener más detalles, consulta «Aplicar el índice».
Ejemplo 1: Indexar una clave de nivel superior con AUTOINDEX
Indexe el campo category para filtrar rápidamente por categoría de producto. Con AUTOINDEX, Milvus selecciona BITMAP o STL_SORT en función del número de categorías distintas que existan en sus datos.
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="category_index",
params={
"json_path": 'metadata["category"]',
"json_cast_type": "VARCHAR",
}
)
Ejemplo 2: Indexar una clave anidada
Indexa el campo « email », profundamente anidado, para la búsqueda de contactos de proveedores. El parámetro « json_path » admite cualquier profundidad de notación entre corchetes.
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="email_index",
params={
"json_path": 'metadata["supplier"]["contact"]["email"]',
"json_cast_type": "VARCHAR",
}
)
Ejemplo 3: Consultas de rango con STL_SORT
Cuando sepa que sus consultas en una ruta estarán dominadas por comparaciones de rango (>, <, >=, <=), seleccione directamente « STL_SORT ». Esto evita la medición de cardinalidad y crea el diseño ordenado de forma inmediata.
index_params.add_index(
field_name="metadata",
index_type="STL_SORT",
index_name="price_index",
params={
"json_path": 'metadata["price"]',
"json_cast_type": "DOUBLE",
}
)
Tras la indexación, las consultas de rango como metadata["price"] > 50 AND metadata["price"] < 100 utilizan la búsqueda binaria en lugar de un escaneo completo.
Ejemplo 4: Consultas de igualdad con BITMAP
Para claves de baja cardinalidad, como códigos de estado, valores booleanos o cadenas tipo enumeración, elige directamente BITMAP. Las consultas de igualdad y del tipo IN se convierten en operaciones de mapa de bits.
index_params.add_index(
field_name="metadata",
index_type="BITMAP",
index_name="in_stock_index",
params={
"json_path": 'metadata["in_stock"]',
"json_cast_type": "BOOL",
}
)
BITMAP También resulta muy adecuado para campos como una columna de tipo « status » con unos pocos valores de cadena distintos.
Ejemplo 5: Convertir el tipo de datos al crear el índice
Cuando los datos numéricos se almacenan por error como cadenas, utiliza « STRING_TO_DOUBLE » para convertir el valor en un número durante la creación del índice.
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="string_to_double_index",
params={
"json_path": 'metadata["string_price"]',
"json_cast_type": "DOUBLE",
"json_cast_function": "STRING_TO_DOUBLE",
}
)
Si la conversión falla para una fila (por ejemplo, una cadena no numérica como « "invalid" »), esa fila se omite durante la indexación.
Ejemplo 6: Indexar objetos JSON completos
A partir de Milvus 3.0.0, la indexación de objetos JSON completos (json_cast_type="JSON"), también conocida como indexación plana de JSON, ha quedado obsoleta. Los índices existentes y las nuevas solicitudes de creación de índices siguen siendo compatibles, pero este modo ya no se recomienda para nuevas cargas de trabajo. Crea índices de ruta JSON para rutas de consulta conocidas. Para documentos JSON complejos o en evolución con patrones de consulta amplios, considere el uso de «JSON Shredding». El «JSON Shredding» no acelera los valores dentro de las matrices; utilice índices de ruta JSON con tipos de conversión de matriz para esas consultas.
Para las cargas de trabajo existentes compatibles, al establecer « json_cast_type="JSON" » se indexa la estructura completa en la ruta indicada. Milvus aplana los objetos anidados en rutas e infiere automáticamente el tipo de cada valor. Todas las claves bajo la ruta pasan a ser buscables.
AUTOINDEX Utiliza de forma transparente « INVERTED » para el tipo de conversión « JSON », ya que el aplanamiento y la inferencia de tipos son capacidades del índice invertido.
Indexar todo el objeto ` metadata `:
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="metadata_full_index",
params={
"json_path": "metadata",
"json_cast_type": "JSON",
}
)
O indexar un subobjeto, como toda la información de « supplier »:
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="supplier_index",
params={
"json_path": 'metadata["supplier"]',
"json_cast_type": "JSON",
}
)
La indexación de objetos completos aumenta el tamaño del índice. Para nuevas cargas de trabajo con documentos profundamente anidados y patrones de consulta diversos, utiliza índices específicos de ruta o considera el uso de JSON Shredding.
Aplicar el índice
Una vez añadidos todos los parámetros del índice, aplícalos a tu colección:
client.create_index(
collection_name="your_collection_name",
index_params=index_params
)
Las creaciones de índices se ejecutan de forma asíncrona. Utiliza client.describe_index(...) para comprobar el estado de creación de un índice específico. El campo « state » muestra « Finished » una vez finalizada la creación, y « total_rows », « indexed_rows » y « pending_index_rows » muestran el progreso a lo largo del proceso.
client.describe_index(
collection_name="your_collection_name",
index_name="category_index",
)
Respuesta de ejemplo:
{
"json_path": "metadata[\"category\"]",
"json_cast_type": "VARCHAR",
"index_type": "AUTOINDEX",
"field_name": "metadata",
"index_name": "category_index",
"total_rows": 20,
"indexed_rows": 20,
"pending_index_rows": 0,
"state": "Finished"
}
Una vez que state indique Finished, las consultas realizadas en la ruta indexada utilizarán automáticamente el nuevo índice.
Para las entradas de AUTOINDEX, el campo index_type de esta respuesta se muestra como AUTOINDEX. Actualmente, Milvus no revela qué estructura subyacente (BITMAP o STL_SORT) se eligió en el momento de la compilación. Considera esta elección como una optimización interna: las consultas de igualdad, IN y de rango sobre la ruta funcionarán independientemente de la estructura seleccionada.
Preguntas frecuentes
¿Cómo elijo entre AUTOINDEX y un tipo de índice explícito?
Empieza con AUTOINDEX. Este tipo selecciona el diseño adecuado en función de la cardinalidad de tus datos y cubre la mayoría de las consultas de igualdad, IN, y de rango sobre rutas JSON. Elige un tipo explícito cuando:
Conozcas tu patrón de consulta (por ejemplo, si siempre utilizas consultas de rango, utiliza
STL_SORT, y si siempre realizas consultas de igualdad sobre valores de baja cardinalidad, utilizaBITMAP) y quieras omitir la medición de la cardinalidad.Necesites consultas de coincidencia de texto o de subcadenas. Utiliza
INVERTED.Estás indexando tipos de conversión de matriz. Utiliza
INVERTEDde forma explícita.Estás manteniendo un índice JSON de objeto completo ya existente. Tanto
INVERTEDcomoAUTOINDEXsiguen siendo compatibles por motivos de compatibilidad, pero la indexación JSON de objeto completo queda obsoleta a partir de Milvus 3.0.0.
¿Qué ocurre si la expresión de filtro de una consulta utiliza un tipo diferente al tipo de conversión del índice?
Si tu expresión de filtro utiliza un tipo diferente al json_cast_type del índice, Milvus no utilizará el índice y podría recurrir a un escaneo por fuerza bruta más lento si los datos lo permiten. Para obtener el mejor rendimiento, alinea siempre tu expresión de filtro con el tipo de conversión del índice. Por ejemplo, si se crea un índice numérico con ` json_cast_type="DOUBLE"`, solo las condiciones de filtro numéricas aprovecharán el índice.
¿Qué ocurre si una clave JSON tiene tipos de datos inconsistentes entre diferentes entidades?
Los tipos inconsistentes pueden dar lugar a una indexación parcial. Por ejemplo, si metadata["price"] se almacena tanto como número (99.99) como cadena ("99.99") y se crea un índice con json_cast_type="DOUBLE", solo se indexarán los valores numéricos. Las entradas en forma de cadena se omitirán y no aparecerán en los resultados del filtro. Utiliza json_cast_function="STRING_TO_DOUBLE" para convertir las cadenas en números en el momento de la indexación, o corrige los datos de origen para que todas las entradas tengan el mismo tipo.
¿Puedo crear varios índices sobre la misma clave JSON?
No. Milvus permite como máximo un índice por cada par « (field, json_path) », independientemente del tipo de conversión o del tipo de índice. No se puede crear a la vez un índice « INVERTED » y un índice « BITMAP » en la misma ruta, ni dos índices en la misma ruta con tipos de conversión diferentes. Sin embargo, sí se puede crear un índice sobre todo el objeto JSON y otro índice independiente sobre una clave anidada dentro de ese objeto, ya que se trata de rutas diferentes.
¿Cómo se ajusta el umbral BITMAP frente a STL_SORT de AUTOINDEX?
Por defecto, AUTOINDEX elige BITMAP cuando los valores indexados tienen 100 o menos valores distintos y STL_SORT en los demás casos. Puedes anular este umbral añadiendo "bitmap_cardinality_limit" a los parámetros de tu índice (rango: 1-1000):
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="category_index",
params={
"json_path": 'metadata["category"]',
"json_cast_type": "VARCHAR",
"bitmap_cardinality_limit": 200, # use BITMAP up to 200 distinct values
}
)
La mayoría de los usuarios no necesitan ajustar este valor. Auméntalo si tienes un campo de cardinalidad moderada que prefieras que se represente mediante mapa de bits; redúcelo para que AUTOINDEX se utilice antes que STL_SORT. La configuración se ignora cuando se especifica explícitamente INVERTED, STL_SORT o BITMAP.