使用sort命令可以对给定的链表、集合、有序集合中的元素进行排序。
- redis默认将要排序的元素看作数字,封装成双精度的浮点数进行比较、排序
- redis内部使用快速排序算法进行排序;
sort实现:
- 服务器执行sort members命令的详细步骤:
- 创建一个和members长度相同的数组,该数组的每个项都是一个redisSortObject结构;
- 遍历数组,将各个数组项的obj指针分别指向members列表的各个项,构成obj指针和列表项之间的一对一关系;
- 遍历数组,将各个obj指针所指向的列表项转成一个double浮点数(或根据选项转成字符串),并将其保存在相应数组项的score属性中;
- 根据score属性,对数组进行排序;
- 遍历数组,将各个obj指针所指向的列表向作为排序结果返回给客户端;
一般用法:
1 | 127.0.0.1:6379> lrange list1 0 -1 |
1)使用alpha选项,对字符串进行排序:
默认情况下,redis是按照数字进行排序的,通过alpha选项可以按照字符串排序。1
2
3
4
5127.0.0.1:6379> sort list2 alpha
1) "a"
2) "g"
3) "y"
4) "z"
2)使用asc、desc选项,进行升序、降序排序:
默认情况下, redis是按照升序排的,可以指定desc选项进行降序排列。1
2
3
4
5127.0.0.1:6379> sort list1 desc
1) "9"
2) "6"
3) "3"
4) "1"
使用limit分页显示排序结果:
用法:sort key limit offset count
- offset:跳过已经排序元素数量;
- count:要返回已排序元素数量;
1
2
3
4
5
6
7
8
9127.0.0.1:6379> sort list2 alpha
1) "a"
2) "g"
3) "y"
4) "z"
127.0.0.1:6379> sort list2 alpha limit 2 2
1) "y"
2) "z"
##by选项,使用外部key进行排序:
在默认情况下, sort命令使用被排序键包含的元素作为排序权重,即:元素本身决定了元素在排序之后所处的位置。通过by选项,sort命令可以指定某些字符串键、hash键的某些域作为元素的权重,进行排序。
uid | username{id} | userlevel{id} |
---|---|---|
1 | admin | 999 |
2 | jack | 10 |
3 | peter | 25 |
4 | mary | 70 |
1 | 把uid 加入到一个链表 |
get选项,获取外部键:
1)默认情况下,sort命令对键进行排序之后,总是返回被排序键本身所包含的元素。通用get选项,sort命令可以在对键排序之后,根据被排序的元素,以及get选项指定的模式,查找并返回某些键值的值。
1 | redis 127.0.0.1:6379> sort uid get user_name_* |
以上代码先排序uid,再取出键username{uid}的值。
2)获取多个外部键:
1 | redis 127.0.0.1:6379> sort uid get user_level_* get user_name_* |
以下代码就按 uid 分别获取 userlevel{uid} 和 username{uid}
3)get有一个额外的参数规则,那就是可以用 # 获取被排序键的值:1
2
3
4
5
6
7
8
9
10
11
12
13redis 127.0.0.1:6379> sort uid get # get user_level_* get user_name_*
1) "1" # uid
2) "9999" # level
3) "admin" # name
4) "2"
5) "10"
6) "jack"
7) "3"
8) "25"
9) "peter"
10) "4"
11) "70"
12) "mary"
以下代码就将 uid 的值、及其相应的 userlevel 和 username 都返回为结果
4)not-exists-key获取外部键但不进行排序:
通过将一个不存在的键作为参数传给 by 选项, 可以让 sort 跳过排序操作,直接返回结果。这种用法在单独使用时,没什么实际用处。不过,通过将这种用法和get选项配合,就可以在不排序的情况下,获取多个外部键,相当于执行一个整合的获取操作(类似于 sql数据库的join关键字)。
1 | redis 127.0.0.1:6379> sort uid by not-exists-key |
下面的代码,在不引起排序的情况下,使用sort、by和get获取多个外部键:
1 | redis 127.0.0.1:6379> sort uid by not-exists-key get # get user_level_* get user_name_* |
将hash表作为get或by的值:
uid | username{id} | userlevel{id} |
---|---|---|
1 | admin | 999 |
2 | jack | 10 |
3 | peter | 25 |
4 | mary | 70 |
我们可以不将用户的名字和级别保存在 username{uid} 和 userlevel{uid} 两个字符串键中, 而是用一个带有 name 域和 level 域的哈希表 userinfo{uid} 来保存用户的名字和级别信息:
1 | redis 127.0.0.1:6379> hmset user_info_1 name admin level 9999 |
之后, by 和 get 选项都可以用 key->field 的格式来获取哈希表中的域的值, 其中 key 表示哈希表键, 而 field 则表示哈希表的域:
1 | redis 127.0.0.1:6379> sort uid by user_info_*->level |
stor选项,保存排序结果:
默认情况下, sort操作只是简单地返回排序结果,并不进行任何保存操作。通过给 store 选项指定一个 key 参数,可以将排序结果保存到给定的键上。如果被指定的 key 已存在,那么原有的值将被排序结果覆盖。
1 | 127.0.0.1:6379> sort userid |