如何在多个字段上对排行榜进行排序?
最后更新于 2024 年 3 月 22 日
问题
如何执行多维排序操作?
答案
在排行榜中,如果需要根据不同的维度进行排序,例如根据玩家的分数对玩家进行排序,如果分数相同,则根据排名进行排序,然后根据完成任务的时间进行排序,可以使用两种方法对分数进行建模。
在排序集中对分数进行编码
此方法使用排序集,并使用自定义分数对不同的字段进行编码。我们将把三个分数编码为一个双精度数字,它由三个部分组成
- 主要分数,可变且无界
- 排名,它有一个上限。例如 999
- 时间,它有一个上限。例如 99999
因此,我们将对该条目的总分数进行编码
HSET user:score:11 score 10 ranking 15 time 1000
如下所示,将以下字符从左到右连接起来
"10" + "015" + "01000" = 1001501000
现在可以使用排序集对排行榜进行建模。
ZADD leaderboard 1001501000 user:score:11
ZADD leaderboard 5000902000 user:score:12
ZADD leaderboard 1002002000 user:score:13
ZADD leaderboard 1002502000 user:score:14
ZADD leaderboard 1003002000 user:score:15
ZADD leaderboard 1003502000 user:score:16
现在,用户将根据三个分数进行自然排序。
ZREVRANGE leaderboard 0 -1
1) "user:score:12"
2) "user:score:16"
3) "user:score:15"
4) "user:score:14"
5) "user:score:13"
6) "user:score:11"
使用 FT.AGGREGATE 进行索引和聚合
使用不同的数据模型,其中每个用户对象都存储用于排序的字段,您可以将分数建模为 `NUMERIC SORTABLE` 字段,并请求 `SORTBY` 属性列表。请查看以下示例。
HSET user:score:11 user user:11 score 10 ranking 15 time 1000
HSET user:score:12 user user:12 score 50 ranking 9 time 2000
HSET user:score:13 user user:13 score 10 ranking 20 time 2000
HSET user:score:14 user user:14 score 10 ranking 25 time 2000
HSET user:score:15 user user:15 score 10 ranking 30 time 2000
HSET user:score:16 user user:16 score 10 ranking 35 time 2000
FT.CREATE user_score_idx ON HASH PREFIX 1 user:score SCHEMA user AS user TEXT score AS score NUMERIC SORTABLE ranking AS ranking NUMERIC SORTABLE time AS time NUMERIC SORTABLE
FT.AGGREGATE user_score_idx * SORTBY 6 @score DESC @ranking DESC @time DESC
1) (integer) 6
2) 1) "score"
2) "50"
3) "ranking"
4) "9"
5) "time"
6) "2000"
3) 1) "score"
2) "10"
3) "ranking"
4) "35"
5) "time"
6) "2000"
4) 1) "score"
2) "10"
3) "ranking"
4) "30"
5) "time"
6) "2000"
5) 1) "score"
2) "10"
3) "ranking"
4) "25"
5) "time"
6) "2000"
6) 1) "score"
2) "10"
3) "ranking"
4) "20"
5) "time"
6) "2000"
7) 1) "score"
2) "10"
3) "ranking"
4) "15"
5) "time"
6) "1000"
参考资料
请查看有关 FT.AGGREGATE 的文档。