Sim, conjuntos ordenados são muito rápidos e poderosos. Eles parecem uma combinação muito melhor para seus requisitos do que
SORT
operações. A complexidade do tempo é muitas vezes mal compreendida. O(log(N)) é muito rápido e escala muito bem. Nós o usamos para dezenas de milhões de membros em um conjunto classificado. A recuperação e a inserção são sub-milissegundos. Use
ZRANGEBYSCORE key min max WITHSCORES [LIMIT offset count]
para obter seus resultados. Dependendo de como você armazena os timestamps como 'pontuações', ZREVRANGEBYSCORE pode ser melhor.
Uma pequena observação sobre os timestamps:Conjunto ordenado
SCORES
que não precisam de uma parte decimal devem usar 15 dígitos ou menos. Portanto, o SCORE
deve permanecer no intervalo -999999999999999 a 999999999999999. Nota:Esses limites existem porque o servidor Redis realmente armazena a pontuação (float) como uma representação de cadeia de redis internamente. Portanto, recomendo este formato, convertido para Zulu Time:-20140313122802 para segunda precisão. Você pode adicionar 1 dígito para precisão de 100 ms, mas não mais se você não quer perda de precisão. A propósito, ainda é um float64, então a perda de precisão pode ser boa em alguns cenários, mas seu caso se encaixa na faixa de 'precisão perfeita', então é isso que eu recomendo.
Se seus dados expirarem em 10 anos, você também poderá pular os três primeiros dígitos (CCY de CCYY), para obter uma precisão de 0,0001 segundo.
Sugiro pontuações negativas aqui, para que você possa usar o
ZRANGEBYSCORE
mais simples em vez do REV
1. Você pode usar -inf
como a pontuação inicial (menos infinito) e LIMIT 0 100
para obter os 100 melhores resultados. Dois conjuntos ordenados
members
(ou 'keys'
mas isso é ambíguo, pois o conjunto classificado também é uma chave em si) pode compartilhar uma score
, isso não é problema, os resultados dentro de uma score
idêntica são alfabéticos. Espero ter ajudado, tw
Editar após o bate-papo
O OP queria coletar dados (usando um
ZSET
) de diferentes chaves (GET
/SET
ou HGET
/HSET
chaves). JOIN
pode fazer isso por você, ZRANGEBYSCORE
não pode. A maneira preferida de fazer isso é um script Lua simples. O script Lua é executado no servidor. No exemplo abaixo eu uso EVAL
para simplificar, na produção você usaria SCRIPT EXISTS
, SCRIPT LOAD
e EVALSHA
. A maioria das bibliotecas de cliente tem alguma lógica de contabilidade integrada, portanto, você não carrega o script toda vez. Aqui está um
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
Você usa assim (exemplo bruto, não codificado para desempenho) :
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
Resultado:
1) "1"
2) "act1JSON"
3) "2"
4) "act2JSON"