Redis®*: Suche und JSON
JSON-Dokumente speichern und effizient mit der Redis-Abfrage-Engine durchsuchen
👋 Willkommen in der Stackhero-Dokumentation!
Stackhero bietet eine einsatzbereite Redis Cloud-Lösung mit zahlreichen Vorteilen, darunter:
Redis CommanderWeb-Oberfläche inklusive.- Unbegrenzte Nachrichtengröße und Übertragungen.
- Updates ganz einfach per Klick.
- Optimale Performance und starke Sicherheit durch eine private, dedizierte Infrastruktur.
Sparen Sie Zeit und vereinfachen Sie Ihren Alltag: Es dauert nur 5 Minuten, um die Redis Cloud Hosting-Lösung von Stackhero auszuprobieren!
Ihre Redis-Instanz auf Stackhero enthält alle in Redis Open Source verfügbaren Module. Diese Module machen Redis zu weit mehr als nur einem Cache: Sie können echte JSON-Dokumente speichern, indizieren und direkt Volltext-, numerische und Tag-Abfragen ausführen. Es ist nicht erforderlich, eine zusätzliche Datenbank in Ihren Stack zu integrieren.
Alle vier unten aufgeführten Module sind in Ihrem Tarif enthalten:
- JSON (
JSON.*-Befehle): Fügt einen nativen JSON-Typ mit JSONPath-Unterstützung hinzu. Sie können einzelne Felder lesen oder aktualisieren, ohne das gesamte Dokument neu zu schreiben. - Search (
FT.*-Befehle), auch bekannt als Redis Query Engine: Bietet Volltextsuche, sekundäre Indizierung, Aggregationen und Vektorsuche. - Bloom (
BF.*,CF.*,CMS.*,TOPK.*,TDIGEST.*-Befehle): Probabilistische Datenstrukturen, die effizient Fragen wie „Habe ich das schon gesehen?“ über große Datenmengen mit minimalem Speicherbedarf beantworten. - Time series (
TS.*-Befehle): Bietet einen Time-Series-Typ mit Aufbewahrung, Downsampling und Aggregationsfunktionen.
Vector sets (VADD, VSIM) sind direkt in Redis integriert. Sie ermöglichen eine effiziente Vektorsuche für Embeddings und stehen in Ihrem Service immer zur Verfügung. Eine Konfiguration ist nicht erforderlich.
Module aktivieren
Module sind standardmäßig deaktiviert. Dadurch wird sichergestellt, dass bestehende Services ihr ursprüngliches Verhalten beibehalten, bis Sie sich entscheiden, neue Funktionen zu aktivieren.
- Öffnen Sie Ihren Service im Stackhero Dashboard.
- Gehen Sie zur Service-Konfiguration.
- Wählen Sie im Abschnitt Modules die gewünschten Module aus.
- Speichern Sie Ihre Änderungen.
Ihr Redis-Service wird mit den ausgewählten Modulen neu gestartet. Dieser Vorgang dauert in der Regel nur wenige Sekunden.
Sobald Sie Daten mit einem Modul speichern (z. B. ein JSON-Dokument, einen Bloom-Filter oder eine Time Series), lassen Sie dieses Modul aktiviert. Redis kann nicht auf Daten zugreifen, die von einem deaktivierten Modul erstellt wurden, und dessen Deaktivierung verhindert den Start Ihres Services. Vector sets sind immer verfügbar, da sie Teil von Redis selbst sind.
Um zu prüfen, welche Module aktuell geladen sind, können Sie folgenden Befehl ausführen:
redis-cli -u "rediss://default:<yourPassword>@<XXXXXX>.stackhero-network.com:<PORT_TLS>" MODULE LIST
JSON-Dokumente speichern
Sie können Dokumente nativ als JSON speichern, anstatt sie als Strings zu serialisieren:
JSON.SET product:1 $ '{"name":"Espresso machine","brand":"Bianca","price":459,"tags":["coffee","kitchen"],"stock":12}'
Mit diesem Ansatz können Sie einzelne Felder atomar und serverseitig lesen oder aktualisieren:
JSON.GET product:1 $.price
# "[459]"
JSON.NUMINCRBY product:1 $.stock -1
# "[11]"
JSON.ARRAPPEND product:1 $.tags '"gift"'
Dieser Workflow spart Aufwand und reduziert Fehler. Beispielsweise muss beim Dekrementieren eines Lagerbestandszählers nicht das gesamte Dokument in Ihrer Anwendung gelesen, geparst und neu geschrieben werden. Stattdessen erfolgt die Änderung sicher und unmittelbar auf dem Server.
Die vollständige Liste der Befehle finden Sie in der Redis JSON Dokumentation.
Dokumente indizieren und durchsuchen
Sie müssen einen Index nur einmal deklarieren. Redis hält ihn dann automatisch für alle Schlüssel mit dem gewählten Präfix aktuell – auch für solche, die bereits vor der Indexerstellung existierten.
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
Nun können Sie Abfragen wie diese ausführen:
# Volltextsuche im Namen mit Preisbereich
FT.SEARCH productsIndex "@name:(espresso) @price:[0 500]"
# Exakte Markensuche, sortiert nach Preis
FT.SEARCH productsIndex "@brand:{Bianca}" SORTBY price ASC
# Präfixsuche für Autovervollständigung
FT.SEARCH productsIndex "@name:(espr*)"
Redis kann auch Aggregationen direkt auf dem Index ausführen, sodass Sie analytische Abfragen beantworten können, ohne Daten zu exportieren:
FT.AGGREGATE productsIndex "*"
GROUPBY 1 @brand
REDUCE COUNT 0 AS products
REDUCE AVG 1 @price AS averagePrice
SORTBY 2 @products DESC
Wenn Sie Daten in einfachen Hashes statt als JSON speichern, können Sie ON HASH und Standard-Feldnamen im Schema verwenden.
Beispiel: Verwendung mit Node.js
import { createClient, SCHEMA_FIELD_TYPE } from 'redis';
const client = createClient({ url: process.env.STACKHERO_REDIS_URL_TLS });
await client.connect();
// Index beim Start erstellen
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();
Beispiel: Verwendung mit 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)
# Index beim Start erstellen
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)
Gut zu wissen
- Search-Indizes funktionieren nur auf Datenbank 0.
FT.CREATEgibt auf anderen Datenbanken einen Fehler zurück. Wenn Ihre Anwendung mehrere logische Datenbanken verwendet, speichern Sie indexierbare Daten auf Datenbank 0 oder trennen Sie verschiedene Datensätze mit Schlüsselpräfixen. - Indizes nutzen den Arbeitsspeicher Ihres Tarifs, genau wie Ihre Daten. Große Text- oder Vektorindizes können erheblich sein, daher sollten Sie nach dem Aufbau
used_memoryin Ihren Prometheus-Metriken überwachen. - Das Erstellen eines Indexes auf bestehenden Schlüsseln läuft im Hintergrund ab. Direkt nach
FT.CREATEkönnen Suchanfragen vorübergehend unvollständige Ergebnisse liefern. Den Fortschritt der Indexierung können Sie mitFT.INFO productsIndexüberwachen. - Alle Modulbefehle sind vollständig verfügbar. Jeder Befehl jedes aktivierten Moduls steht in Ihrem Service bereit.
Weitere Informationen zu Vektorsuche, semantischer Suche oder Retrieval-Augmented Generation finden Sie im Leitfaden zur Vektorsuche.