Redis®*: Paieška ir JSON
Saugojimas JSON dokumentų ir efektyvus jų užklausimas naudojant Redis užklausų variklį
👋 Sveiki atvykę į Stackhero dokumentaciją!
Stackhero siūlo paruoštą naudoti Redis cloud sprendimą, kuris suteikia daugybę privalumų, įskaitant:
- Įtraukta
Redis Commanderžiniatinklio sąsaja.- Neribotas žinučių dydis ir perdavimas.
- Paprasti atnaujinimai vienu paspaudimu.
- Optimali veikla ir stipri apsauga dėl privačios, dedikuotos infrastruktūros.
Taupykite laiką ir palengvinkite sau darbą: išbandyti Stackhero Redis cloud hosting sprendimą užtrunka tik 5 minutes!
Jūsų Redis instancijoje Stackhero aplinkoje įtraukti visi Redis Open Source galimi moduliai. Šie moduliai paverčia Redis kur kas daugiau nei tik talpykla: galite saugoti tikrus JSON dokumentus, juos indeksuoti ir vykdyti pilno teksto, skaitines bei žymų (tag) užklausas tiesiogiai. Nereikia į savo infrastruktūrą pridėti dar vienos duomenų bazės.
Visi keturi žemiau išvardinti moduliai yra įtraukti į jūsų planą:
- JSON (
JSON.*komandos): Prideda natyvinį JSON tipą su JSONPath palaikymu. Galite skaityti ar atnaujinti atskirus laukus neperrašydami viso dokumento. - Search (
FT.*komandos), dar vadinamas Redis užklausų varikliu: Suteikia pilno teksto paiešką, antrinį indeksavimą, agregacijas ir vektorinės paieškos galimybes. - Bloom (
BF.*,CF.*,CMS.*,TOPK.*,TDIGEST.*komandos): Tikimybinės duomenų struktūros, kurios efektyviai atsako į klausimus, pvz., „ar jau esu tai matęs?“, net ir su labai dideliais duomenų rinkiniais, naudojant minimaliai atminties. - Time series (
TS.*komandos): Suteikia laiko eilučių (time series) tipą su duomenų saugojimo, sumažinimo (downsampling) ir agregavimo funkcijomis.
Vector sets (VADD, VSIM) yra integruoti tiesiogiai į Redis. Jie leidžia efektyviai atlikti vektorinės panašumo paieškas (vector similarity search) embedding'ams ir visada yra prieinami jūsų paslaugoje. Jokios papildomos konfigūracijos nereikia.
Modulių įjungimas
Pagal numatymą moduliai yra išjungti. Tai užtikrina, kad esamos paslaugos išlaikytų savo pradinį elgesį, kol nuspręsite įjungti naujas funkcijas.
- Atidarykite savo paslaugą Stackhero valdymo skydelyje.
- Eikite į paslaugos konfigūraciją.
- Modules skiltyje pasirinkite norimus modulius.
- Išsaugokite pakeitimus.
Jūsų Redis paslauga bus paleista iš naujo su pasirinktais moduliais. Šis procesas paprastai trunka kelias sekundes.
Kai tik saugote duomenis naudodami modulį (pvz., JSON dokumentą, Bloom filtrą ar laiko eilutę), laikykite tą modulį įjungtą. Redis negali pasiekti duomenų, sukurtų išjungtu moduliu, o jo išjungimas neleis paslaugai startuoti. Vector sets visada prieinami, nes jie yra Redis dalis.
Norėdami patikrinti, kurie moduliai šiuo metu įkelti, galite vykdyti:
redis-cli -u "rediss://default:<yourPassword>@<XXXXXX>.stackhero-network.com:<PORT_TLS>" MODULE LIST
JSON dokumentų saugojimas
Dokumentus galite saugoti natyviai kaip JSON, o ne serializuoti juos į eilutes:
JSON.SET product:1 $ '{"name":"Espresso machine","brand":"Bianca","price":459,"tags":["coffee","kitchen"],"stock":12}'
Šis būdas leidžia skaityti ar atnaujinti atskirus laukus atomiškai ir serverio pusėje:
JSON.GET product:1 $.price
# "[459]"
JSON.NUMINCRBY product:1 $.stock -1
# "[11]"
JSON.ARRAPPEND product:1 $.tags '"gift"'
Toks darbo procesas taupo laiką ir sumažina klaidų tikimybę. Pavyzdžiui, norint sumažinti sandėlio kiekį, nereikia skaityti, parsinant ir perrašyti viso dokumento aplikacijoje – viskas vyksta saugiai ir iš karto serveryje.
Visą komandų sąrašą rasite Redis JSON dokumentacijoje.
Tų dokumentų indeksavimas ir paieška
Indeksą reikia deklaruoti tik vieną kartą. Redis automatiškai palaikys jį atnaujintą visiems raktams, atitinkantiems pasirinktą prefiksą, įskaitant ir tuos, kurie egzistavo iki indekso sukūrimo.
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
Dabar galite vykdyti tokias užklausas kaip:
# Pilno teksto paieška pagal pavadinimą ir kainos intervalą
FT.SEARCH productsIndex "@name:(espresso) @price:[0 500]"
# Tikslus prekės ženklo atitikimas, rūšiuojant pagal kainą
FT.SEARCH productsIndex "@brand:{Bianca}" SORTBY price ASC
# Prefikso paieška automatinio užbaigimo scenarijams
FT.SEARCH productsIndex "@name:(espr*)"
Redis taip pat gali atlikti agregacijas tiesiogiai indekse, todėl galite gauti analitinius atsakymus neišeksportuodami duomenų:
FT.AGGREGATE productsIndex "*"
GROUPBY 1 @brand
REDUCE COUNT 0 AS products
REDUCE AVG 1 @price AS averagePrice
SORTBY 2 @products DESC
Jei duomenis saugote paprastuose hash'uose, o ne JSON, galite naudoti ON HASH ir standartinius laukų pavadinimus savo schemoje.
Pavyzdys: naudojant Node.js
import { createClient, SCHEMA_FIELD_TYPE } from 'redis';
const client = createClient({ url: process.env.STACKHERO_REDIS_URL_TLS });
await client.connect();
// Indekso sukūrimas paleidimo metu
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();
Pavyzdys: naudojant 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)
# Indekso sukūrimas paleidimo metu
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)
Svarbu žinoti
- Search indeksai veikia tik 0 duomenų bazėje.
FT.CREATEkitose duomenų bazėse grąžina klaidą. Jei jūsų aplikacija naudoja kelias logines duomenų bazes, laikykite indeksuojamus duomenis 0 bazėje arba naudokite raktų prefiksus skirtingiems duomenų rinkiniams atskirti. - Indeksai naudoja jūsų plano atmintį, kaip ir duomenys. Dideli tekstiniai ar vektoriniai indeksai gali užimti reikšmingą dalį, todėl po jų sukūrimo stebėkite
used_memorysavo Prometheus metrikose. - Indekso kūrimas esamiems raktams vyksta fone. Iškart po
FT.CREATEpaieškos gali trumpam grąžinti nepilnus rezultatus. Indeksavimo eigą galite stebėti suFT.INFO productsIndex. - Visos modulių komandos yra pilnai prieinamos. Kiekviena įjungto modulio komanda yra paruošta naudoti jūsų paslaugoje.
Norėdami sužinoti daugiau apie vektorinį panašumą, semantinę paiešką ar retrieval-augmented generation, žiūrėkite vektorinės paieškos vadovą.