七. Redis 有序集合(sorted set)操作
Redis 有序集合是 string 类型元素的集合,每个元素会关联一个 double 类型的分数,通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 2的32次方减 1 (4294967295, 每个集合可存储40多亿个成员)。
1. zAdd - 向有序集合添加一个或多个成员,或者更新已存在成员的分数
// 添加操作是返回添加成员个数;如果是更新已存在成员的分数,无论是否成功都返回0
$redis->zAdd('key', 6, 'v1', 2,'v2', 3,'v3');
2. zCard - 获取有序集合的成员数
// 返回集合成员数,整型
$res = $redis->zCard('key');
3. zCount - 计算在有序集合中指定区间分数的成员数
// 返回整型值
$redis->zCount('key',1,6);
4. zIncrBy - 有序集合中对指定成员的分数加上增量 increment
// 返回值为 key 集合的成员 v2 当前的分数值
$redis->zIncrBy('key',6,'v2');
5. zInterStore - 计算给定的一个或多个有序集的交集并将结果存储在新的有序集合中
redis->del('k1');
$redis->del('k2');
$redis->del('k3');
$redis->del('ko1');
$redis->del('ko2');
$redis->del('ko3');
$redis->del('ko4');
$redis->zAdd('k1', 0,'val0');
$redis->zAdd('k1', 1,'val1');
$redis->zAdd('k1', 3,'val3');
$redis->zAdd('k2',2,'val1');
$redis->zAdd('k2',3,'val3');
// 返回保存到目标结算集的成员数量, 新集合中成员分数为合并集合中该成员的分数之和
$redis->zInterStore('ko1', array('k1','k2'));
$redis->zInterStore('ko2', array('k1','k2'), array(1,1));
// 返回保存到目标结算集的成员数量, 新集合中成员分数为合并集合中该成员的分数最小值
$redis->zInterStore('ko3', array('k1', 'k2'), array(1,5),'min');
$redis->zInterStore('ko3', array('k1', 'k2'), array(1,5),'max');
6. zRange - 通过索引区间返回有序集合指定区间内的成员
$redis->zAdd('key1', 0, 'val0');
$redis->zAdd('key1',2,'val2');
$redis->zAdd('key1',10,'val10');
// 返回包含成员的数组,键名不存在时返回空数组
$redis->zRange('key1',0,-1);
/* 输出
array(3) {
[0]=>
string(4) "val0"
[1]=>
string(4) "val2"
[2]=>
string(5) "val10"
}
*/
// 返回以成员-分数为键值的数组
$redis->zRange('key1',0,-1,true);
/*输出
array(3) {
["val0"]=>
float(0)
["val2"]=>
float(2)
["val10"]=>
float(10)
}
*/
7. zRangeByLex- 通过字典区间返回有序集合的成员
// zRangeByLex- 通过字典区间返回有序集合的成员
foreach(['a','b','c','d','e','f','g'] as $k=>$v){
$redis->zAdd('key',$k,$v);
}
// '-'号代表最小值; '[' 号代表包含
$redis->zRangeByLex('key','-','[c');
/* 输出
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
}
*/
'(' 号代表不包含成员
$redis->zRangeByLex('key','-','(c');
/* 输出
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
}
*/
'+' 号代表最大值
$res = $redis->zRangeByLex('key','-','+');
/* 输出
array(7) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
[3]=>
string(1) "d"
[4]=>
string(1) "e"
[5]=>
string(1) "f"
[6]=>
string(1) "g"
}
*/
8. zRangeByScore - 通过分数返回有序集合指定区间内的成员
// 通过分数返回有序集合指定区间内的成员
$redis->zAdd('key',0,'val0');
$redis->zAdd('key',2,'val2');
$redis->zAdd('key', 10,'val10');
$redis->zRangeByScore('key',0,3);
/* 输出
array(2) {
[0]=>
string(4) "val0"
[1]=>
string(4) "val2"
}
*/
// 该方法带上第三个参数与不带的测试效果一样
//$redis->zRangeByScore('key', 0, 3, array('WITHSCORES' => TRUE));
//$redis->zRangeByScore('key',0,3,['LIMIT'=> [1,1]]);
9. zRank - 返回有序集合中指定成员的索引
// 成功返回0,失败返回false
$rs = $redis->zRank('key','val3');
10. zRem - 移除有序集合中的一个或多个成员
// 成功返回1,失败返回0
$rs = $redis->zRem('key','val0');
11. zRemRangeByRank - 移除有序集合中给定的排名区间的所有成员
$redis->zAdd('key',1,'one');
$redis->zAdd('key',2,'two');
$redis->zAdd('key',3,'three');
// 返回移除成员数
$redis->zRemRangeByRank('key',0,1);
/* 输出
int(2)
*/
12. zRemRangeByScore - 移除有序集合中给定的分数区间的所有成员
$redis->zAdd('key',0,'val0');
$redis->zAdd('key',2,'val2');
$redis->zAdd('key',10,'val10');
// 返回移除成员数
$redis->zRemRangeByScore('key',0,3);
/* 输出
int(2)
*/
13. zRevRange - 返回有序集中指定区间内的成员,通过索引,分数从高到低
$redis->zAdd('key',0,'val0');
$redis->zAdd('key',2,'val2');
$redis->zAdd('key',10,'val10');
$redis->zRevRange('key',0,-1);
/* 输出
array(3) {
[0]=>
string(5) "val10"
[1]=>
string(4) "val2"
[2]=>
string(4) "val0"
}
*/
$redis->zRevRange('key',0,-1, true);
/* 输出
array(3) {
["val10"]=>
float(10)
["val2"]=>
float(2)
["val0"]=>
float(0)
}
*/
14. zRevRange - 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
$redis->zAdd('key',0,'val0');
$redis->zAdd('key',2,'val2');
$redis->zAdd('key',10,'val10');
$redis->zRevRange('key', 0,-1);
/* 输出
array(3) {
[0]=>
string(5) "val10"
[1]=>
string(4) "val2"
[2]=>
string(4) "val0"
}
*/
$redis->zRevRange('key', 0,-1, true);
/* 输出
array(3) {
["val10"]=>
float(10)
["val2"]=>
float(2)
["val0"]=>
float(0)
}
*/
15. zScore - 返回有序集中,成员的分数值
// 成功时返回成员分数,失败时返回 false
$redis->zScore('key','val10');
16. zUnionStore - 计算给定的一个或多个有序集的并集,并存储在新的 key 中
$redis->del('k1');
$redis->del('k2');
$redis->del('k3');
$redis->del('ko1');
$redis->del('ko2');
$redis->del('ko3');
$redis->zAdd('k1', 0,'val0');
$redis->zAdd('k1', 1,'val1');
$redis->zAdd('k2', 2,'val2');
$redis->zAdd('k2', 3,'val3');
$redis->zUnionStore('ko1', array('k1','k2'));
var_dump($redis->zRange('ko1',0,-1));
/* 输出
array(4) {
[0]=>
string(4) "val0"
[1]=>
string(4) "val1"
[2]=>
string(4) "val2"
[3]=>
string(4) "val3"
}
*/
// 该方法第三个参数是为每个给定的有序集合指定一个乘法因子, 每个给定有序集合的所有成员的score值在传递给聚合函数之前都要先乘以该因子
$redis->zUnionStore('ko2', array('k1','k2'),array(1,1));
var_dump($redis->zRange('ko2',0,-1));
/*
array(4) {
[0]=>
string(4) "val0"
[1]=>
string(4) "val1"
[2]=>
string(4) "val2"
[3]=>
string(4) "val3"
}
*/
$redis->zUnionStore('ko3', array('k1','k2'),array(5,1));
var_dump($redis->zRange('ko3',0,-1));
/* 输出
array(4) {
[0]=>
string(4) "val0"
[1]=>
string(4) "val2"
[2]=>
string(4) "val3"
[3]=>
string(4) "val1"
}
*/
17. zscan - 用于迭代有序集合中的元素
$redis->zAdd('site', 1,'google', 2,'runoob',3,'taobao', 4,'weibo');
$iterator = null;
while ($members = $redis->zScan('site', $iterator)){
foreach ($members as $member=>$score){
echo $member . '=>' . $score . PHP_EOL;
}
}
// 输出
/*
google=>1
runoob=>2
taobao=>3
weibo=>4
*/