我需要创建一个具有最大元素数的排行榜,比如 N ?我知道如何使用 LPUSH + LTRIM 将列表大小限制为 N 个元素。如何使用 Redis 排序集为排行榜实现此功能
到目前为止,我的方法是分 3 步完成:a) ZADD 将分数 + 项目添加到排行榜
b)找到第 N 个元素的排名(我不知道该怎么做)
c) 做一个 ZREMRANGEBYRANK 排行榜 0 rank_of_the_nth_element。
有没有更好的办法 ?
我需要创建一个具有最大元素数的排行榜,比如 N ?我知道如何使用 LPUSH + LTRIM 将列表大小限制为 N 个元素。如何使用 Redis 排序集为排行榜实现此功能
到目前为止,我的方法是分 3 步完成:a) ZADD 将分数 + 项目添加到排行榜
b)找到第 N 个元素的排名(我不知道该怎么做)
c) 做一个 ZREMRANGEBYRANK 排行榜 0 rank_of_the_nth_element。
有没有更好的办法 ?
我实际上有一个使用 redis 的有效排行榜应用程序。你可以在这里查看。在我的应用程序中,排行榜受到最高n
分数的限制,并且旧分数在太旧时也会下降(因此可能会有日、周、月、年的高分板)。
无论如何,我认为你想要做的是一个整体的排行榜,所以低分会被推迟。在 Redis Sorted Set 分数的意义上,如果你设置了它,那么高分应该保留(它们在底部)而低分应该离开(它们在顶部),那么你会做类似的事情:
ZREMRANGBYRANK leaderboard 0 -100
该示例假设您要保留最后 100 个分数。
也许您将分数反转,因此 1000 的“高分”在 redis 中存储为 -1000,因此它是排序集中的第一个。在这种情况下,它与上述相同,但用于ZREMRANGEBYRANK leaderboard 100 -1
删除前 100 个之后的所有项目。
更新:意识到我的例子是ZREMRANGEBYRANK
如此简化。
您提出的解决方案也应该有效。如果你想找到nth
元素的分数,你可以使用这个:
hundredth_entry = ZRANGE leaderboard 100 100
hundredth_score = ZSCORE leaderboard hundredth_entry
ZREMRANGEBYSCORE leaderboard -inf (hundredth_score
是为了(
使范围不包括在内,因此任何小于百分之一的分数都将被删除,而不是百分之一的分数本身。
OP算法的lua实现:
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
然后更换
ZADD key score member
和
EVAL script 1 key score member cap