Descripción general del campo JSON
Al crear aplicaciones como catálogos de productos, sistemas de gestión de contenidos o motores de preferencias de usuario, a menudo es necesario almacenar metadatos flexibles junto con las incrustaciones vectoriales. Los atributos de los productos varían según la categoría, las preferencias de los usuarios evolucionan con el tiempo y las propiedades de los documentos tienen estructuras anidadas complejas. Los campos JSON en Milvus resuelven este desafío permitiéndole almacenar y consultar datos estructurados flexibles sin sacrificar el rendimiento.
¿Qué es un campo JSON?
Un campo JSON es un tipo de datos definido por esquema (DataType.JSON) en Milvus que almacena datos estructurados clave-valor. A diferencia de las columnas rígidas tradicionales de las bases de datos, los campos JSON admiten objetos anidados, matrices y tipos de datos mixtos, a la vez que proporcionan múltiples opciones de indexación para consultas rápidas.
Ejemplo de estructura de campo JSON:
{
"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"
}
}
}
}
En este ejemplo, metadata es un único campo JSON que contiene una mezcla de valores planos (por ejemplo, category, in_stock), matrices (tags) y objetos anidados (supplier).
Convención de nomenclatura: Utilice sólo letras, números y guiones bajos en las claves JSON. Evite caracteres especiales, espacios o puntos, ya que pueden causar problemas de análisis en las consultas.
Campo JSON frente a campo dinámico
Un punto común de confusión es la diferencia entre un campo JSON y el campo dinámico. Aunque ambos están relacionados con JSON, tienen propósitos diferentes.
La siguiente tabla resume las principales diferencias entre un campo JSON y un campo dinámico:
Característica |
Campo JSON |
Campo dinámico |
|---|---|---|
Definición de esquema |
Un campo escalar que debe declararse explícitamente en el esquema de la colección con el tipo |
Un campo JSON oculto (denominado |
Caso de uso |
Almacena datos estructurados cuyo esquema es conocido y coherente. |
Almacena datos flexibles, en evolución o semiestructurados que no se ajustan a un esquema fijo. |
Control |
Usted controla el nombre y la estructura del campo. |
Gestionado por el sistema para campos no definidos. |
Consulta |
Consulta utilizando el nombre del campo o la clave de destino dentro del campo JSON: |
Consulta directa utilizando la clave dinámica del campo: |
Operaciones básicas
El flujo de trabajo fundamental para utilizar un campo JSON implica definirlo en su esquema, insertar datos y, a continuación, consultar los datos utilizando expresiones de filtro específicas.
Definir un campo JSON
Para utilizar un campo JSON, defínalo explícitamente en el esquema de la colección al crearla. El siguiente ejemplo muestra cómo crear una colección con un campo metadata de tipo DataType.JSON:
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="http://localhost:19530") # Replace with your server address
# Create schema
schema = client.create_schema(auto_id=False, enable_dynamic_field=True)
schema.add_field(field_name="product_id", datatype=DataType.INT64, is_primary=True) # Primary field
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5) # Vector field
# Define a JSON field that allows null values
schema.add_field(field_name="metadata", datatype=DataType.JSON, nullable=True)
client.create_collection(
collection_name="product_catalog",
schema=schema
)
En este ejemplo, el campo JSON definido en el esquema de la colección permite valores nulos con nullable=True. Para obtener más información, consulte Nullable & Default.
Insertar datos
Una vez creada la colección, inserte entidades que contengan objetos JSON estructurados en su campo JSON designado. Sus datos deben tener el formato de una lista de diccionarios.
entities = [
{
"product_id": 1,
"vector": [0.1, 0.2, 0.3, 0.4, 0.5],
"metadata": { # JSON field
"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"
}
}
}
}
]
client.insert(collection_name="product_catalog", data=entities)
Operaciones de filtrado
Antes de poder realizar operaciones de filtrado en campos JSON, asegúrese de:
Ha creado un índice en cada campo vectorial.
La colección está cargada en memoria.
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector",
index_type="AUTOINDEX",
index_name="vector_index",
metric_type="COSINE"
)
client.create_index(collection_name="product_catalog", index_params=index_params)
client.load_collection(collection_name="product_catalog")
Una vez cumplidos estos requisitos, puede utilizar las siguientes expresiones para filtrar la colección en función de los valores del campo JSON. Estas expresiones de filtrado aprovechan la sintaxis de ruta JSON específica y los operadores dedicados.
Filtrado con sintaxis de ruta JSON
Para consultar una clave específica, utilice la notación de corchetes para acceder a las claves JSON: json_field_name["key"]. Para claves anidadas, encadénelas: json_field_name["key1"]["key2"].
Para filtrar entidades en las que category es "electronics":
# Define filter expression
filter = 'metadata["category"] == "electronics"'
client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)
Para filtrar entidades en las que la clave anidada supplier["country"] es "USA":
# Define filter expression
filter = 'metadata["supplier"]["country"] == "USA"'
res = client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)
print(res)
Filtrado con operadores específicos de JSON
Milvus también proporciona operadores especiales para consultar valores de array en claves de campo JSON específicas. Por ejemplo
json_contains(identifier, expr): Comprueba si existe un elemento o subarray específico dentro de un array JSONjson_contains_all(identifier, expr): Comprueba si todos los elementos de la expresión JSON especificada están presentes en el campojson_contains_any(identifier, expr): Filtra las entidades en las que existe al menos un miembro de la expresión JSON dentro del campo
Para encontrar un producto que tenga el valor "summer_sale" bajo la clave tags:
# Define filter expression
filter = 'json_contains(metadata["tags"], "summer_sale")'
res = client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)
print(res)
Para encontrar un producto que tenga al menos uno de los valores "electronics", "new", o "clearance" bajo la clave tags:
# Define filter expression
filter = 'json_contains_any(metadata["tags"], ["electronics", "new", "clearance"])'
res = client.search(
collection_name="product_catalog", # Collection name
data=[[0.1, 0.2, 0.3, 0.4, 0.5]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression
output_fields=["product_id", "metadata"] # Fields to include in the search results
)
print(res)
Para obtener más información sobre los operadores específicos de JSON, consulte Operadores JSON.
A continuación: Acelerar las consultas JSON
Por defecto, las consultas sobre campos JSON sin aceleración realizarán una exploración completa de todas las filas, lo que puede resultar lento en conjuntos de datos de gran tamaño. Para acelerar las consultas JSON, Milvus proporciona funciones avanzadas de indexación y optimización del almacenamiento.
La siguiente tabla resume sus diferencias y los mejores escenarios de uso:
Técnica |
Mejor para |
Matrices Aceleración |
Notas |
|---|---|---|---|
Indexación JSON |
Pequeño conjunto de claves de acceso frecuente, arrays en una clave de array específica |
Sí (en clave de matriz indexada) |
Debe preseleccionar las claves, mantenimiento necesario si el esquema evoluciona |
Trituración JSON |
Aceleración general de muchas claves, flexible para consultas variadas |
No (no acelera valores dentro de matrices) |
Configuración de almacenamiento adicional, las matrices siguen necesitando un índice por clave |
Índice NGRAM |
Búsquedas con comodines, coincidencia de subcadenas en campos de texto |
NO |
No para filtros numéricos/de rango |
Sugerencia: puede combinar estos enfoques; por ejemplo, utilice la fragmentación JSON para acelerar las consultas generales, la indexación JSON para las claves de arrays de alta frecuencia y la indexación NGRAM para realizar búsquedas de texto flexibles.
Para obtener más información, consulte
PREGUNTAS FRECUENTES
¿Existen limitaciones en el tamaño de un campo JSON?
Sí. Cada campo JSON está limitado a 65.536 bytes.
¿Admite un campo JSON un valor por defecto?
No, los campos JSON no admiten valores por defecto. Sin embargo, puede configurar nullable=True al definir el campo para permitir entradas vacías.
Consulte Nullable & Default para más detalles.
¿Existen convenciones de nomenclatura para las claves de los campos JSON?
Sí, para garantizar la compatibilidad con las consultas y la indexación:
Utilice sólo letras, números y guiones bajos en las claves JSON.
Evite utilizar caracteres especiales, espacios o puntos (
.,/, etc.).Las claves incompatibles pueden causar problemas de análisis en las expresiones de filtro.
¿Cómo maneja Milvus los valores de cadena en los campos JSON?
Milvus almacena los valores de cadena exactamente como aparecen en la entrada JSON, sin transformación semántica. Las cadenas entrecomilladas incorrectamente pueden dar lugar a errores durante el análisis.
Ejemplos de cadenas válidas:
"a\"b", "a'b", "a\\b"
Ejemplos de cadenas no válidas:
'a"b', 'a\'b'