本专栏与Redis相关的文章html
Redis Sentinel机制与用法(一)
Redis Sentinel机制与用法(二)
Jedis的JedisSentinelPool源代码分析
Jedis的Sharded源代码分析
Redis 主从 Replication 的配置
详解Redis SORT命令
JedisCommand接口说明redis
命令格式: SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination] segmentfault
默认状况下,排序是基于数字的,各个元素将会被转化成双精度浮点数来进行大小比较,这是SORT
命令最简单的形式,也就是下面这种形式:微信
SORT mylist
markdown
若是mylist
是一个包含了数字元素的列表,那么上面的命令将会返回升序排列的一个列表。若是想要降序排序,要使用DESC
描述符,以下所示:编辑器
SORT mylist DESC
性能
若是mylist
包含的元素是string类型的,想要按字典顺序排列这个列表,那么就要用到ALPHA
描述符,以下所示:编码
SORT mylist ALPHA
spa
Redis是基于UTF-8编码来处理数据的, 要确保你先设置好了!LC_COLLATE环境变量。code
对于返回的元素个数也是能够进行限制的,只须要使用LIMIT
描述符。使用这个描述符,你须要提供偏移量参数,来指定须要跳过多少个元素,返回多少个元素。 下面这个例子将会返回一个已经排序好了的列表中的10个元素,从下标为0开始:
SORT mylist LIMIT 0 10
几乎所有的描述符均可以同时使用。例以下面这个例子所示,它将会返回前5个元素,以字典顺序降序排列:
SORT mylist LIMIT 0 5 ALPHA DESC
有时候,你会想要用外部的key来做为权重去排列列表或集合中的元素,而不是使用列表或集合中原本就有的元素来排列。
下面以一个例子来解释:
假设如今有一张这样的表(顺便吐槽一下,为何这个markdown编辑器不支持表格,非要写html代码吗),有商品id,商品价格,以及商品的重量。
首先将上述表格的数据导入到redis中(redis版本:2.8.6)
127.0.0.1:6379> lpush gid 1 (integer) 1 127.0.0.1:6379> lpush gid 2 (integer) 2 127.0.0.1:6379> lpush gid 3 (integer) 3 127.0.0.1:6379> lpush gid 4 (integer) 4 127.0.0.1:6379> set price_1 20 OK 127.0.0.1:6379> set price_2 40 OK 127.0.0.1:6379> set price_3 30 OK 127.0.0.1:6379> set price_4 10 OK 127.0.0.1:6379> set weight_1 3 OK 127.0.0.1:6379> set weight_2 2 OK 127.0.0.1:6379> set weight_3 4 OK 127.0.0.1:6379> set weight_4 1 OK
默认状况下对gid排序,只会按gid的值来排序
127.0.0.1:6379> sort gid 1) "1" 2) "2" 3) "3" 4) "4"
可是经过BY描述符,能够指定gid按照别的key来排序。例如我想要按照商品的价格来排序:
127.0.0.1:6379> sort gid by price_* 1) "4" 2) "1" 3) "3" 4) "2"
能够看到,gid为4的商品价格最低,为10,gid为2的商品价格最高,为40。
在这里,price_*中的*是一个占位符,先会把gid的值取出,代入到*中,再去查找price_*的值。例如在本例中,price_*中的*会分别被1,2,3,4代替,而后去取price_1,price_2,price_3,price_4的值来进行排序。
BY描述符也可使用一个根本不存在的key来做为排序规则,则直接致使的结果就是不进行任何排序。 这看上去彷佛没什么用,可是若是你想要取得外部的keys时,跳过排序就很是有用了,这也会减小性能损耗。
要理解不排序的好处,首先要先了解一下GET描述符。
使用GET描述符,能够根据排序结果取出外部键值。例如如下命令:
127.0.0.1:6379> sort gid get price_* 1) "20" 2) "40" 3) "30" 4) "10"
先对gid排序,而后再分别取出price_{gid}的值。
也可使用多个GET,获取多个外部key的值,例如:
127.0.0.1:6379> sort gid get price_* get weight_* 1) "20" # 这是price 2) "3" # 这是weight,如下类推 3) "40" 4) "2" 5) "30" 6) "4" 7) "10" 8) "1"
get也可使用#来获取被排序的key的值,例如:
127.0.0.1:6379> sort gid get # get price_* 1) "1" #这里取出的就是gid 2) "20" #这里是price,如下类推 3) "2" 4) "40" 5) "3" 6) "30" 7) "4" 8) "10"
经过结合不排序和GET,可以在不排序的状况下,一次取得多个key的值。例如:
127.0.0.1:6379> sort gid by no-existed get # get price_* get weight_* 1) "4" #这是gid 2) "10" #这是price 3) "1" #这是weight,如下类推 4) "3" 5) "30" 6) "4" 7) "2" 8) "40" 9) "2" 10) "1" 11) "20" 12) "3"
默认状况下,排序结果会返回给客户端。使用STORE描述符,能够将结果存储在指定key上,若是Key已经存在,则覆盖。而不将排序结果返回给客户端。用法以下:
SORT mylist BY weight_* STORE resultkey
下面举一个例子:
127.0.0.1:6379> rpush num 1 3 5 (integer) 3 127.0.0.1:6379> rpush num 2 4 6 (integer) 6 127.0.0.1:6379> lrange num 0 -1 1) "1" 2) "3" 3) "5" 4) "2" 5) "4" 6) "6" 127.0.0.1:6379> sort num store num_sorted (integer) 6 127.0.0.1:6379> lrange num_sorted 0 -1 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "6"
能够将哈希表的字段做为GET或者BY的参数,用法以下:
SORT mylist BY weight_*->fieldname GET object_*->fieldname
对于前面所用到的例子:
咱们能够不把price_{gid}和weight_{id}用string类型来保存,而是对于每个gid,建立一个包含price和weight字段的hash表good_info_{gid}来存储商品信息。
127.0.0.1:6379> hmset good_info_1 price 20 weight 3 OK 127.0.0.1:6379> hmset good_info_2 price 40 weight 2 OK 127.0.0.1:6379> hmset good_info_3 price 30 weight 4 OK 127.0.0.1:6379> hmset good_info_4 price 10 weight 1 OK
以后, by 和 get 选项均可以用 key->field 的格式来获取哈希表中的域的值, 其中 key 表示哈希表键, 而 field 则表示哈希表的域:
127.0.0.1:6379> sort gid by good_info_*->price 1) "4" 2) "1" 3) "3" 4) "2" 127.0.0.1:6379> sort gid by good_info_*->price get good_info_*->weight 1) "1" 2) "3" 3) "4" 4) "2"
若是没有使用 store 描述符,返回列表形式的排序结果。
若是使用 store 参数,返回排序结果的元素数量。
Redis官网SORT命令介绍