Redis 中的sort命令
SORT命令
Redis的SORT命令可以实现对列表、集合有有序集合类型键进行排序,操作类似于关系数据库的连接查询的功能。在对有序集合类型排序的时候,SORT会忽略有序集合元素本身的score
而只是参考键值进行排序。SORT
默认会将键值转换成浮点数之后进行排序,如果转换失败则会报错。对于元素为字符串的情形,我们可以传入ALPHA
的参数使其按照字典的顺序排序。SORT
命令默认按照从小到大的顺序排序,如果需要从大到小排序可以加上DESC
参数。
- 列表排序示例
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']
- 集合排序示例
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']
- 有序列表排序示例
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']
好了,今天redis
的SORT
命令就写这么多。
最后更新于 2017-06-08 14:04:32 并被添加「python reids」标签,已有 2470 位童鞋阅读过。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。