Ja, sorterede sæt er meget hurtige og kraftfulde. De ser ud til at passe meget bedre til dine krav end SORT
operationer. Tidskompleksiteten bliver ofte misforstået. O(log(N)) er meget hurtig og skalerer fint. Vi bruger det til titusinder af medlemmer i ét sorteret sæt. Hentning og indsættelse er sub-millisekunder.
Brug ZRANGEBYSCORE key min max WITHSCORES [LIMIT offset count]
for at få dine resultater.
Afhængigt af hvordan du gemmer tidsstemplerne som 'score', kan ZREVRANGEBYSCORE være bedre.
En lille bemærkning om tidsstemplerne:Sorteret sæt SCORES
som ikke behøver en decimaldel, skal bruge 15 cifre eller mindre. Så SCORE
skal forblive i intervallet -999999999999999 til 9999999999999999. Bemærk:Disse grænser eksisterer, fordi Redis-serveren faktisk gemmer partituret (float) som en redis-streng-repræsentation internt.
Jeg anbefaler derfor dette format, konverteret til Zulu Time:-20140313122802 for anden præcision. Du kan tilføje 1 ciffer for 100ms-præcision, men ikke mere hvis du ønsker intet tab af præcision. Det er i øvrigt stadig en float64, så tab af præcision kunne være fint i nogle scenarier, men din sag passer i området 'perfekt præcision', så det er det, jeg anbefaler.
Hvis dine data udløber inden for 10 år, kan du også springe de tre første cifre (CCY af CCYY) over for at opnå 0,0001 sekunders præcision.
Jeg foreslår negative resultater her, så du kan bruge den mere simple ZRANGEBYSCORE
i stedet for REV
en. Du kan bruge -inf
som startscore (minus uendeligt) og LIMIT 0 100
for at få de 100 bedste resultater.
To sorterede sæt members
(eller 'keys'
men det er tvetydigt, da det sorterede sæt også er en nøgle i sig selv) kan dele en score
, det er ikke noget problem, resultaterne inden for en identisk score
er alfabetiske.
Håber dette hjælper, TW
Rediger efter chat
OP ønskede at indsamle data (ved hjælp af en ZSET
) fra forskellige nøgler (GET
/SET
eller HGET
/HSET
nøgler). JOIN
kan gøre det for dig, ZRANGEBYSCORE
kan ikke. Den foretrukne måde at gøre dette på er et simpelt Lua-script. Lua-scriptet udføres på serveren. I eksemplet nedenfor bruger jeg EVAL
For nemheds skyld ville du i produktionen bruge SCRIPT EXISTS
, SCRIPT LOAD
og EVALSHA
. De fleste klientbiblioteker har en bogføringslogik indbygget, så du uploader ikke scriptet hver gang.
Her er en example.lua
:
local r={}
local zkey=KEYS[1]
local a=redis.call('zrangebyscore', zkey, KEYS[2], KEYS[3], 'withscores', 'limit', 0, KEYS[4])
for i=1,#a,2 do
r[i]=a[i+1]
r[i+1]=redis.call('get', a[i])
end
return r
Du bruger det sådan her (råt eksempel, ikke kodet til ydeevne) :
redis-cli -p 14322 set activity:1 act1JSON
redis-cli -p 14322 set activity:2 act2JSON
redis-cli -p 14322 zadd feed 1 activity:1
redis-cli -p 14322 zadd feed 2 activity:2
redis-cli -p 14322 eval '$(cat example.lua)' 4 feed '-inf' '+inf' 100
Resultat:
1) "1"
2) "act1JSON"
3) "2"
4) "act2JSON"