Redis 中的sort命令

SORT命令

Redis的SORT命令可以实现对列表、集合有有序集合类型键进行排序,操作类似于关系数据库的连接查询的功能。在对有序集合类型排序的时候,SORT会忽略有序集合元素本身的score而只是参考键值进行排序。SORT默认会将键值转换成浮点数之后进行排序,如果转换失败则会报错。对于元素为字符串的情形,我们可以传入ALPHA的参数使其按照字典的顺序排序。
SORT命令默认按照从小到大的顺序排序,如果需要从大到小排序可以加上DESC参数。

  1. 列表排序示例
In [3]: r.lpush("list_example", 3, 9, 5, 6, 2, 1, 7)
Out[3]: 7

In [6]: r.sort("list_example")
Out[6]: ['1', '2', '3', '5', '6', '7', '9']

In [7]: r.sort("list_example", desc=True)
Out[7]: ['9', '7', '6', '5', '3', '2', '1']

In [10]: r.sort("list_example", desc=True, alpha=True)
Out[10]: ['world', 'hello', 'a', '9', '7', '6', '5', '3', '2', '1']
  1. 集合排序示例
In [12]: r.sadd('set_example', 9, 8, 12, 3, 19)
Out[12]: 5

In [13]: r.sort('set_example')
Out[13]: ['3', '8', '9', '12', '19']
  1. 有序列表排序示例
In [20]: r.zrange('zset_example', 0, 10, withscores=True)
Out[20]: [('world', 5.0), ('hello', 20.0), ('jack', 87.0)]

In [21]: r.sort('zset_example', alpha=True)
Out[21]: ['hello', 'jack', 'world']

BY 参数

在一般的应用场景中, 集合会保存一些记录的ID,而记录的真正内容是保存在散列表中的,在需要排序的情景中一般是需要按照散列表的某一个键进行排序(比如时间),这时就需要用到SORT命令的一个强大的参数BY.

BY参数实际是指定一个参考键,它可以是某个字符串类型的键或者散列类型键的某个字段。如果指定了BY参数,SORT命令将不再使用自身的键值排序,而是对每个元素使用元素的值来参考健中的第一个'*'并获取值,然后依据该值进行排序。

应用举例:

In [24]: r.hmset("post:1", {"title":"test", "likes":20})
Out[24]: True

In [25]: r.hmset("post:3", {"title":"python", "likes":2014})
Out[25]: True

In [26]: r.hmset("post:5", {"title":"java", "likes":14})
Out[26]: True

In [27]: r.sadd("post:tags:code", 1, 3, 5)
Out[27]: 3

In [28]: r.sort("post:tags:code", by='post:*->likes')
Out[28]: ['5', '1', '3']

In [29]: r.sort("post:tags:code", by='post:*->likes', desc=True)
Out[29]: ['3', '1', '5']

SORT BY命令还支持GET参数,从前面的例子可以看到,排序返回的是集合键名中的ID,但如果需要返回title怎么办呢,redis中可以通过指定GET参数说明需要哪些返回数据。

In [30]: r.sort("post:tags:code", by='post:*->likes', get="post:*->title", desc=True)
Out[30]: ['python', 'test', 'java']

In [32]: r.sort("post:tags:code", by='post:*->likes', get=["post:*->title", 'post:*->likes'], desc=True, group
    ...: s=True)
Out[32]: [('python', '2014'), ('test', '20'), ('java', '14')]

In [33]: r.sort("post:tags:code", by='post:*->likes', get=["post:*->title", 'post:*->likes', '#'], desc=True,
    ...: groups=True)
Out[33]: [('python', '2014', '3'), ('test', '20', '1'), ('java', '14', '5')]

In [42]: r.sort("post:tags:code", by='post:*->likes', get=["post:*->title", 'post:*->likes'], desc=True, group
    ...: s=True)
Out[42]: [('python', '2014'), ('test', '20'), ('java', '14')]

如果需要返回集合元素的值,get参数需要写成#, group参数好像并不会影响结果。既然如此就用默认的Flase好了,因为group=True的时候STORE 结果的时候会报错。

结果保存STORE

因为SORT命令还是很复杂的,一些情况下,为了避免每次都调用SORT命令,我们可以将结果保存到一个新的列表中,redis支持直接保存SORT结果,命令是STORE.

In [40]: r.sort("post:tags:code", by='post:*->likes', get=["post:*->title", 'post:*->likes', '#'], desc=True,
    ...: store='sort:result')
Out[40]: 9

In [41]: r.lrange('sort:result', 0, -1)
Out[41]: ['python', '2014', '3', 'test', '20', '1', 'java', '14', '5']

好了,今天redisSORT命令就写这么多。


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

相关文章

发表新评论