Ja, sorterade set är mycket snabba och kraftfulla. De verkar vara mycket bättre matchande för dina krav än SORT
operationer. Tidskomplexiteten missförstås ofta. O(log(N)) är mycket snabb och skalar bra. Vi använder det för tiotals miljoner medlemmar i en sorterad uppsättning. Hämtning och insättning är under millisekunder.
Använd ZRANGEBYSCORE key min max WITHSCORES [LIMIT offset count]
för att få dina resultat.
Beroende på hur du lagrar tidsstämplarna som "poäng", kan ZREVRANGEBYSCORE vara bättre.
En liten anmärkning om tidsstämplarna:Sorterad uppsättning SCORES
som inte behöver en decimaldel bör ha 15 siffror eller mindre. Alltså SCORE
måste stanna i intervallet -999999999999999 till 9999999999999999. Obs:Dessa gränser finns eftersom Redis-servern faktiskt lagrar poängen (flytande) som en representation av redis-sträng internt.
Jag rekommenderar därför detta format, konverterat till Zulu Time:-20140313122802 för andra precision. Du kan lägga till 1 siffra för 100ms-precision, men inte mer om du vill inte ha någon förlust i precision. Det är förresten fortfarande en float64, så förlust av precision kan vara bra i vissa scenarier, men ditt fodral passar i intervallet "perfekt precision", så det är vad jag rekommenderar.
Om din data förfaller inom 10 år kan du också hoppa över de tre första siffrorna (CCY av CCYY) för att uppnå 0,0001 sekunders precision.
Jag föreslår negativa poäng här, så att du kan använda den enklare ZRANGEBYSCORE
istället för REV
ett. Du kan använda -inf
som startpoäng (minus oändlighet) och LIMIT 0 100
för att få de 100 bästa resultaten.
Två sorterade set members
(eller 'keys'
men det är tvetydigt eftersom den sorterade uppsättningen också är en nyckel i sig) kan dela en score
, det är inga problem, resultaten inom en identisk score
är alfabetiska.
Hoppas detta hjälper, TW
Redigera efter chatt
OP ville samla in data (med hjälp av en ZSET
) från olika nycklar (GET
/SET
eller HGET
/HSET
nycklar). JOIN
kan göra det åt dig, ZRANGEBYSCORE
kan inte. Det föredragna sättet att göra detta är ett enkelt Lua-skript. Lua-skriptet körs på servern. I exemplet nedan använder jag EVAL
För enkelhetens skull skulle du använda SCRIPT EXISTS
i produktionen , SCRIPT LOAD
och EVALSHA
. De flesta klientbibliotek har en viss bokföringslogik inbyggd, så du laddar inte upp skriptet varje gång.
Här är 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 använder det så här (råexempel, inte kodad för prestanda) :
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"