2012-10-11 52 views
6

Necesito crear una tabla de clasificación con la cantidad máxima de elementos, digamos N? Sé cómo usar LPUSH + LTRIM para limitar el tamaño de una lista a N elementos. Cómo implementar este de clasificación utilizando un Redis SortedSetCómo limitar una tabla de clasificación en Redis a solo N elementos?

Hasta ahora mi enfoque es hacer esto en 3 pasos: a) Zadd añadir una puntuación + elemento de la tabla de clasificación

b) encontrar el rango de la enésima elemento (no estoy seguro de cómo hacer esto)

c) hacer una tabla de clasificación ZREMRANGEBYRANK 0 rank_of_the_nth_element.

¿Hay una manera mejor?

Respuesta

5

De hecho, tengo una aplicación de clasificación de trabajo que usa redis. Puede verificarlo here. En mi aplicación, las tablas de líderes están limitadas por los puntajes más altos n, y también los puntajes viejos se dejan cuando son demasiado viejos (por lo que puede haber tablas de puntuación máxima de día, semana, mes y año).

De todos modos, creo que lo que estás buscando hacer es una tabla de clasificación general, por lo que los puntajes bajos se eliminan. En el sentido de los puntajes del conjunto ordenado de Redis, si lo tiene configurado, los puntajes altos deberían permanecer (están en la parte inferior) y los puntajes bajos deberían salir (están en la parte superior) y luego haría algo como:

ZREMRANGBYRANK leaderboard 0 -100 

Ese ejemplo supone que desea mantener los últimos 100 puntajes.

Tal vez invierta los puntajes, por lo que un "puntaje alto" de 1000 se almacena como -1000 en redis, por lo que es el primero en el conjunto ordenado. En ese caso, sería el mismo que el anterior, pero el uso de ZREMRANGEBYRANK 100 -1 para eliminar todos los artículos después de la primera 100.

Actualización: di cuenta de que es ZREMRANGEBYRANK modo simplificado mi ejemplo.

Su solución propuesta debería funcionar también. Si usted quiere encontrar la puntuación del elemento nth, puede utilizar esto:

hundredth_entry = ZRANGE leaderboard 100 100 
hundredth_score = ZSCORE leaderboard hundredth_entry 
ZREMRANGEBYSCORE leaderboard -inf (hundredth_score 

El ( está ahí para hacer que el rango NO incluido, por lo que se eliminará cualquier cosa menos que la puntuación centésima pero no la puntuación centésima sí mismo.

1

Una implementación del algoritmo de lua OP:

redis.call("ZADD", KEYS[1], ARGV[1]+0, ARGV[2]) 
local n = redis.call("ZCARD", KEYS[1]) 
if n > ARGV[3]+0 then 
    redis.call("ZREMRANGEBYRANK", KEYS[1], 0, n-ARGV[3]-1) 
end 

luego vuelva a colocar

ZADD key score member 

con

EVAL script 1 key score member cap 
Cuestiones relacionadas