如何在多个字段上对排行榜进行排序?

最后更新时间:2024 年 3 月 22 日

问题

如何执行多维度排序操作?

回答

在排行榜中,如果您需要在不同维度上进行排序:例如,根据玩家得分排序,如果得分相同,则按排名排序,然后按完成任务的时间排序,则可以使用两种方法来建模分数。

在有序集合中编码分数

此方法使用带有自定义分数编码不同字段的有序集合。我们将把三个分数编码为一个由三部分组成的双精度数

  1. 主要分数,可变且无界
  2. 排名,具有上限。例如 999
  3. 时间,具有上限。例如 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 的文档。