问题描述
我有 2 个排序集作为排名。我想从他们之间的联盟中获得前 5 名。分数是一样的。
zadd rank1 1 aaa
zadd rank1 2 bbb
zadd rank1 3 ccc
zadd rank1 4 ddd
zadd rank2 1 aaa
zadd rank2 2 bbb
zadd rank2 3 ccc
zadd rank2 4 ddd
这样做的最佳方法是什么?
ZUINON 10 rank1 rank2 AGGREGATE MAX 5
我会假设类似的东西,但 max 5
不存在。
编辑
刚刚发现即使 ZUNION
也无济于事,因为我的 redis 版本是 6.0.5 而不是 6.2.0
解决方法
我的排序集合很大 - 即每个集合中有数百万个键。另外,这个联合每秒会发生很多次(这是我网站中的首要查询)。这是最快的方法吗?
只需从每个 SortedSet 中取出前 5 个,然后在您的服务器(/客户端)进程中从这 10 个元素中选择前 5 个。对于您的场景,这将是最快且最不复杂的。
您可以使用 ZREVRANGE 命令从一个 SortedSet 中获取前 N 个元素。但是要统一/合并 2xN 元素并选择前 M 个元素,您还需要这些元素的相应分数。带有 ZREVRANGE
关键字的 WITHSCORES
命令返回前 N 个元素及其分数。
ZREVRANGE rank1 0 4 WITHSCORES
ZREVRANGE rank2 0 4 WITHSCORES
,
这取决于你想用同一个键的分数做什么。对于两个'aaa',要不要把它们相加(聚合),然后得到前五名的聚合结果?
您可以使用 ZUNIONSTORE,可以选择将临时结果存储在其他地方,然后获得前五名的结果。 (支持Redis 6以下版本)
要以原子方式执行此操作,您需要一个 lua 脚本来组合以下两个命令
ZUNIONSTORE out 2 rank1 rank2 --(the temporary result is stored in a zset called 'out')
ZREVRANGE out 0 4 ---- (ranking from highest to lowest,get top five)