Redis®*: Búsqueda y JSON
Almacene documentos JSON y consúltelos de forma eficiente con el motor de consultas de Redis
👋 ¡Bienvenido a la documentación de Stackhero!
Stackhero ofrece una solución Redis cloud lista para usar que proporciona numerosas ventajas, entre ellas:
- Interfaz web Redis Commander incluida.
- Tamaño y transferencia de mensajes ilimitados.
- Actualizaciones sencillas con solo un clic.
- Rendimiento óptimo y seguridad reforzada gracias a una infraestructura privada y dedicada.
Ahorre tiempo y simplifique su trabajo: solo necesita 5 minutos para probar la solución de alojamiento Redis cloud de Stackhero.
Su instancia de Redis en Stackhero incluye todos los módulos disponibles en Redis Open Source. Estos módulos convierten Redis en mucho más que una caché: puede almacenar documentos JSON reales, indexarlos y realizar búsquedas de texto completo, numéricas y por etiquetas directamente. No es necesario añadir otra base de datos a su stack.
Los siguientes cuatro módulos están incluidos en su plan:
- JSON (comandos
JSON.*): Añade un tipo JSON nativo con soporte para JSONPath. Puede leer o actualizar campos individuales sin tener que reescribir el documento completo. - Search (comandos
FT.*), también conocido como el motor de consultas de Redis: Proporciona búsqueda de texto completo, indexación secundaria, agregaciones y capacidades de búsqueda vectorial. - Bloom (comandos
BF.*,CF.*,CMS.*,TOPK.*,TDIGEST.*): Estructuras de datos probabilísticas que permiten responder de forma eficiente a preguntas como "¿ya he visto esto?" sobre conjuntos masivos utilizando una cantidad mínima de memoria. - Time series (comandos
TS.*): Ofrece un tipo de serie temporal con retención, downsampling y funciones de agregación.
Los vector sets (VADD, VSIM) están integrados directamente en Redis. Permiten búsquedas vectoriales eficientes para embeddings y siempre están disponibles en su servicio. No necesita realizar ninguna configuración.
Activación de los módulos
Los módulos están desactivados por defecto. Esto garantiza que los servicios existentes mantengan su comportamiento original hasta que decida activar nuevas funcionalidades.
- Abra su servicio en el panel de Stackhero.
- Acceda a la configuración del servicio.
- En la sección Modules, seleccione los módulos que desee.
- Guarde los cambios.
Su servicio Redis se reiniciará con los módulos seleccionados cargados. Este proceso suele completarse en unos segundos.
Una vez que almacene datos utilizando un módulo (como un documento JSON, un filtro Bloom o una serie temporal), mantenga ese módulo activado. Redis no puede acceder a los datos creados por un módulo desactivado y, si lo desactiva, su servicio no podrá arrancar. Los vector sets siempre están disponibles, ya que forman parte del propio Redis.
Para comprobar qué módulos están actualmente cargados, puede ejecutar:
redis-cli -u "rediss://default:<yourPassword>@<XXXXXX>.stackhero-network.com:<PORT_TLS>" MODULE LIST
Almacenamiento de documentos JSON
Puede almacenar documentos de forma nativa como JSON, en lugar de serializarlos como cadenas de texto:
JSON.SET product:1 $ '{"name":"Espresso machine","brand":"Bianca","price":459,"tags":["coffee","kitchen"],"stock":12}'
Este enfoque le permite leer o actualizar campos individuales de forma atómica y en el lado del servidor:
JSON.GET product:1 $.price
# "[459]"
JSON.NUMINCRBY product:1 $.stock -1
# "[11]"
JSON.ARRAPPEND product:1 $.tags '"gift"'
Este flujo de trabajo ahorra esfuerzo y reduce errores. Por ejemplo, decrementar un contador de stock no requiere leer, analizar y reescribir todo el documento en su aplicación. En su lugar, la operación se realiza de forma segura e inmediata en el servidor.
Puede consultar la lista completa de comandos en la documentación de Redis JSON.
Indexación y búsqueda de estos documentos
Solo necesita declarar un índice una vez. Redis lo mantendrá actualizado automáticamente para cada clave que coincida con el prefijo elegido, incluidas las claves que ya existían antes de crear el índice.
FT.CREATE productsIndex
ON JSON
PREFIX 1 product:
SCHEMA
$.name AS name TEXT
$.brand AS brand TAG
$.price AS price NUMERIC SORTABLE
$.tags[*] AS tags TAG
Ahora puede realizar consultas como:
# Búsqueda de texto completo en el nombre, con un rango de precios
FT.SEARCH productsIndex "@name:(espresso) @price:[0 500]"
# Coincidencia exacta de la marca, ordenada por precio
FT.SEARCH productsIndex "@brand:{Bianca}" SORTBY price ASC
# Búsqueda por prefijo para escenarios de autocompletado
FT.SEARCH productsIndex "@name:(espr*)"
Redis también puede realizar agregaciones directamente sobre el índice, por lo que puede responder a consultas analíticas sin exportar los datos:
FT.AGGREGATE productsIndex "*"
GROUPBY 1 @brand
REDUCE COUNT 0 AS products
REDUCE AVG 1 @price AS averagePrice
SORTBY 2 @products DESC
Si almacena los datos en hashes simples en lugar de JSON, puede usar ON HASH y nombres de campo estándar en su esquema.
Ejemplo: Uso con Node.js
import { createClient, SCHEMA_FIELD_TYPE } from 'redis';
const client = createClient({ url: process.env.STACKHERO_REDIS_URL_TLS });
await client.connect();
// Crear el índice al iniciar
try {
await client.ft.create(
'productsIndex',
{
'$.name': { type: SCHEMA_FIELD_TYPE.TEXT, AS: 'name' },
'$.brand': { type: SCHEMA_FIELD_TYPE.TAG, AS: 'brand' },
'$.price': { type: SCHEMA_FIELD_TYPE.NUMERIC, AS: 'price', SORTABLE: true }
},
{ ON: 'JSON', PREFIX: 'product:' }
);
}
catch (error) {
if (!error.message.includes('Index already exists')) {
throw error;
}
}
await client.json.set('product:1', '$', {
name: 'Espresso machine',
brand: 'Bianca',
price: 459
});
const results = await client.ft.search('productsIndex', '@name:(espresso) @price:[0 500]');
console.log(results.total, results.documents);
await client.quit();
Ejemplo: Uso con Python
import os
import redis
from redis.commands.search.field import TextField, TagField, NumericField
from redis.commands.search.index_definition import IndexDefinition, IndexType
from redis.commands.search.query import Query
r = redis.from_url(os.environ['STACKHERO_REDIS_URL_TLS'], decode_responses=True)
# Crear el índice al iniciar
try:
r.ft('productsIndex').create_index(
(
TextField('$.name', as_name='name'),
TagField('$.brand', as_name='brand'),
NumericField('$.price', as_name='price', sortable=True),
),
definition=IndexDefinition(prefix=['product:'], index_type=IndexType.JSON),
)
except redis.ResponseError as error:
if 'Index already exists' not in str(error):
raise
r.json().set('product:1', '$', {
'name': 'Espresso machine',
'brand': 'Bianca',
'price': 459,
})
results = r.ft('productsIndex').search(Query('@name:(espresso) @price:[0 500]'))
print(results.total, results.docs)
Información útil
- Los índices de Search solo funcionan en la base de datos 0.
FT.CREATEdevuelve un error en cualquier otra base de datos. Si su aplicación utiliza varias bases de datos lógicas, mantenga los datos indexables en la base de datos 0, o utilice prefijos de clave para separar los distintos conjuntos de datos. - Los índices utilizan la memoria de su plan, igual que sus datos. Los índices de texto o vectoriales grandes pueden ser significativos, así que puede monitorizar
used_memoryen sus métricas de Prometheus después de crearlos. - La creación de un índice sobre claves existentes se realiza en segundo plano. Justo después de
FT.CREATE, las búsquedas pueden devolver resultados incompletos durante un breve periodo. Puede monitorizar el progreso de la indexación conFT.INFO productsIndex. - Todos los comandos de los módulos están completamente disponibles. Cada comando de cada módulo activado está listo para usar en su servicio.
Para obtener más información sobre búsqueda vectorial, búsqueda semántica o retrieval-augmented generation, consulte la guía de búsqueda vectorial.