2012-10-11 22 views
6

Potrzebuję utworzyć tabelę wyników z maksymalną liczbą elementów, na przykład N? Wiem, jak korzystać z LPUSH + LTRIM, aby ograniczyć rozmiar listy do N elementów. Jak zaimplementować to na tablicy przy użyciu Redis sortedsetJak zamknąć tabelę wyników w Redis tylko dla N elementów?

Dotychczas moje podejście jest, aby zrobić to w 3 krokach: a) ZADD dodać wynik + element do banera

b) Znajdź rangi n-tego element (nie jestem pewien jak to zrobić)

c) Zrób tabelę wyników ZREMRANGEBYRANK 0 rank_the_nth_element.

Czy istnieje lepszy sposób?

Odpowiedz

5

Rzeczywiście mam działającą aplikację na tablicy wyników, która używa redisu. Możesz to sprawdzić here. W mojej aplikacji tablice liderów są ograniczone przez najwyższe wyniki n, a także stare wyniki spadają, gdy są za stare (więc nie może być dzień, tydzień, miesiąc, rok tablice wyników).

W każdym razie myślę, że to, co chcesz zrobić, to ogólna tablica liderów, więc niskie wyniki zostają zepchnięte. W sensie wyników Redis Sorted Set, jeśli masz ustawione tak wysokie wyniki, powinny pozostać (są na dole), a niskie wyniki powinny zostać (są na górze), to zrobiłbyś coś takiego:

ZREMRANGBYRANK leaderboard 0 -100 

Ten przykład zakłada, że ​​chcesz zachować ostatnie 100 wyników.

Może odwrócić wyniki, więc "wysoki wynik" z 1000 jest przechowywany jako -1000 w odcinkach, więc jest pierwszym w posortowanym zestawie. W tym przypadku byłoby to samo co powyżej, ale używać ZREMRANGEBYRANK 100 -1 usunąć wszystkie pozycje po pierwszej 100.

Aktualizacja: Zrealizowany jest ZREMRANGEBYRANK tak uproszczone mój przykład.

Twoje proponowane rozwiązanie również powinno działać. Jeśli chcesz znaleźć wynik elementu nth, można użyć tego:

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

( jest tam, aby sprawić, że zakres nie włącznie, więc niczego mniej niż setną wynik zostanie usunięty, ale nie setnej wynik samo.

1

Implementacja lua algorytmu 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 

Następnie zastąpić

ZADD key score member 

z

EVAL script 1 key score member cap