我们首先看下redis-cli下ZRANGEBYSCORE的用法[这里redis命令都用大写]:
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回有序集key中score在min和max直接的成员(默认闭区间[min, max],可用符号(min, (max来指定为开区间),按score递增排序。可选参数WITHSCORES决定是否要返回score。可选参数LIMIT指定返回偏移量后的数量,不指定则返回全量。
这里着重罗列下取全部成员的方法:
ZRANGEBYSCORE key -inf +inf WITHSCORES
在不知道min或max score的情况下,可以使用-inf、+inf。inf是Redis中Infinity(无穷)的标示。其实ZDD也可以用-inf, +inf:
ZADD key +inf niliu.me
那么,phpredis如何使用zRangeByScore取全量数据呢,查看phpredis文档可以看到描述:+inf and -inf are also valid limits,但是没有例子,Google搜索也没有找到,自己尝试可行的方式如下:
$redis = new Redis(); $redis->connect($ip, $port); $res = $redis->zRangeByScore($key, '-inf', '+inf', $withscores); // zRangeByScore()方法完整的参数如下 // $redis->zRangeByScore($key, $start_score, $end_score, array('withscores' => TRUE, 'limit' => array(1, 1));
需要注意的就是-inf和+inf需要以字符串的方式传递,如果不加引号,语法不会报错,但是返回结果$res为false。
为什么不加引号不会报错呢
$redis->zRangeByScore($key, -inf, +inf, $withscores);
测试发现直接echo不加引号的字母,或者把不加引号的字母赋值给一个变量,会输出一个字符串。如果不加引号的字母前面有+(-)会输出0。
echo hello; // hello $str = hello; var_dump($str); // string(5) "hello" echo +world; // 0
有一种说法是把变量后面不加引号的表达式转为了字符串,自定义变量调用了__toString()方法,没有在官网上找到理论依据。但是可以看出+inf至少跟常量INF无关。
总结
我们发现取有序集合全部数据有两种方法
$redis->zRange($key, 0, -1, true); $res = $redis->zRangeByScore($key, '-inf', '+inf', ['withscores'] => true);
stackoverflow上有一个对比,可见zRange的性能更高:
Time with 10k itterations on 60k elements in zset:
zrange myZset 1 5 WITHSCORES: 0.70670008659363
zrangebyscore myZset -inf +inf WITHSCORES 4 1: 1.0469110012054