20.排序

Redis的SORT命令可以对列表键、集合键、有序集合键进行排序。

 

1.SORT <key>命令的实现

SORT命令最简单的执行形式为:SORT <key>

这个命令可以对一个包含数字值的键key进行排序,示例:

RPUSH numbers 3 1 2

SORT numbers

服务器执行SORT numbers命令的详细步骤如下:

1)创建一个和numbers列表长度相同的数组,该数组的每个项都是一个redis.h/redisSortObject结构

2)遍历数组,将各个数组项的obj指针分别指向numbers列表的各个项,构成obj指针和列表项之间的一对一关系

3)遍历数组,将各个obj指针所指向的列表项转化为一个double类型的浮点数,并将这个浮点数保存在相应数组项u.score属性里

4)根据数组项u.score属性的值,对数组进行数字值排序,排序后的数组项按u.score属性的值从小到大排序

5)遍历数组,将各个数组项的obj指针所指向的列表项作为排序结果返回给客户端

redisSortObject结构的完整定义

typedef struct _redisSortObject{
   //被排序键的值
    robj *obj;

    //权重
    union{
        //排序数字值时使用
        double score;

        //排序带有BY选项的字符串值时使用
        robj *compobj;
    } u;

} redisSortObject;

 

2. ALPHA选项的实现

通过使用ALPHA选项,SORT命令可以对包含字符串值得键进行排序:

SORT <key> ALPHA

示例:

SADD fruits apple banana cherry

SMEMBERS fruits

SORT fruits ALPHA

服务器执行SORT fruits ALPHA命令的详细步骤如下:

1)创建一个redisSortObject结构数组,数组的长度等于fruits集合大小

2)遍历数组,将各个数组项的obj指针分别指向fruits集合的各个元素

3)根据obj指针指向的集合元素,对数组进行字符串排序,排序后的数组项按集合元素的字符串值从小到大排序

4)遍历数组,依次将数组项的obj指针所指向的元素返回给客户端

 

3.ASC选项和DESC选项的实现

在默认情况下,SORT命令执行升序排序,排序后的结构按照从小到大排序:

SORT <key> 等价于 SORT <key> ASC

相反,SORT <key> DESC是从大到小

 

4.BY选项的实现

在默认情况下,SORT命令使用被排序键包含的元素作为排序的权重,元素本身决定了元素在排序之后所处的位置。

另一方面,通过使用BY选项,SORT命令可以指定某些字符串键,或者某个哈希键所包含的某些域作为元素的权重,对一个键进行排序

示例:

MSET apple-price 8 banana-price 5.5 cherry-price 7

SORT fruits BY *-price

详细步骤:

1)创建一个redisSortObject结构数组,数组的长度等于fruits集合的大小

2)遍历数组,将各个数组项的obj指针分别指向fruits集合的各个元素

3)遍历数组,根据各个数组项的obj指针所指向的集合元素,以及BY选项所给定的模式,查找相应的权重键

4)将各个权重键的值转换成一个double类型的浮点数,然后保存在相应数组项的u.score属性里面

5)以数组项u.score属性的值为权重,对数组进行排序,得到一个按u.score属性的值从小到大排序的数组

6)遍历数组,一次将数组的obj指针所指向的集合元素返回给客户端

 

5.带有ALPHA选项的BY选项的实现

BY选项默认假设权重键保存的值为数字值,如果权重键保存的值是字符串值得话,那么就需要在使用BY选项的同时,配合ALPHA选项了。

示例:

SADD fruits "apple" "banbana" "cherry"

MSET apple-id "FRUIT-25" banbana-id "FRUIT-79" cherry-id "FRUIT-13"

SORT fruits BY *-id ALPHA

详细步骤:

1)创建一个redisSortObject结构数组,数组的长度等于fruits集合的大小

2)遍历数组,将各个数组项的obj指针分别指向fruits集合的各个元素

3)遍历数组,根据各个数组项的obj指针所指向的集合元素,以及BY选项所给定的模式,查找相应的权重键

4)将各个数组项的u.cmpobj指针分别指向相应的权重键(一个字符串对象)

5)以各个数组项的权重键的值为权重,对数组执行字符串排序

 

6. LIMIT选项的实现

在默认情况下,SORT命令总会将排序后的所有元素都返回给客户端。

但是通过LIMIT选项,我们可以让SORT命令只返回其中一部分已排序的元素。

LIMIT选项的格式为:LIMIT <offset> <count>;

offset:要跳过的已排序元素数量

count:跳过给定数量的已排序元素之后,要返回的已排序元素数量

示例:

SADD alphabet a b c d e f g 

SMEMBERS alphabet 

SORT alphabet  ALPHA

SORT alphabet  ALPHA LIMIT 0 4

 

7.GET选项的实现

在默认情况下,SORT命令在对键进行排序之后,总是返回被排序键本身所包含的元素。

但是通过GET选项,我们可以让SORT命令在对键进行排序之后,根据被排序的元素,以及GET选项所指定的模式,查找并返回某些键的值。

示例:

SADD students "peter" "jack" "tom"

SORT students ALPHA


SET peter-name "Peter White"

SET jack-name "Jack Snow"

SET tom-name "Tom Smith"

SORT sutdents ALPHA GET *-name

 

8.STORE选项的实现

在默认情况下,SORT命令只向客户端返回排序结果,而不保存排序结果。

但是通过STORE选项,我们可以将排序结果保存在指定的键里面,并在有需要时重用这个排序结果。

示例:

SADD students "peter" "jack" "tom"

SORT students ALPHA

SORT students ALPHA STORE sorted_students

LRANGE sorted_students 0-1

 

9.多个选项的执行顺序

一个SORT命令请求通常会用到多个选项,而这些选项的执行顺序是由先后之分的。

 

9.1 选项的执行顺序

如果按照选项来划分的话,一个SORT命令的执行过程可以分为以下四步:

1)排序:在这一步,命令会使用ALPHA、ASC、DESC、BY这几个选项,对输入键进行排序,并得到一个排序结果集

2)限制排序结果集的长度:在这一步,会使用LIMIT选项对结果集的长度进行限制,只有LIMIT选项指定的那部分元素会被保留在排序结果集中

3)获取外部键:在这一步,命令会使用GET选项,根据排序结果集中的元素以及GET选项指定的模式,查找并获取指定键的值,并用这些值作为新的排序结果集

4)保存排序结果集:在这一步,命令会使用STORE选项,将排序结果及保存到指定的键上面去

5)向客户的返回排序结果集:在最后这一步,命令遍历排序结果集,并以此向客户端返回排序结果集中的元素。

示例:

SORT <key> ALPHA DESC BY <by-pattern> LIMIT <offset> <count> GET <get-pattern> STORE <store-key>

 

9.2 选项的摆放顺序

调用SORT命令时,除了GET选项之外,改变选项的摆放顺序并不会影响SORT命令执行这些选项的顺序。

不过,如果命令包含了多个GET选项,那么在调整选项的位置时,我们必须保证多个GET选项的摆放顺序不变,这才可以让排序结果集保持不变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹏哥哥啊Aaaa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值