探索redis设计与实现1:SpringDataRedis常用API——ZSet

探索redis设计与实现1:SpringDataRedis常用API——ZSet

主要分为如下几类:

(1)增加

(2)删除

(3)获取Zset集合的大小

(4)获取Zset集合的个数(指定score区间)

(5)通过value值获取其对应分数

(6)将score增加指定数值

(7)获取Zset集合中的全部元素(包括值和score)

(8)获取排序后的索引(正反排序情形)

(9)各种排序

(10)交集

(11)并集

(12)rangeByLex使用

以上完成了Zset的全部API(除去事务),其中由于使用的是boundZSetOps,对于opsForZSet类推。


一、基本操作

1. 增加

/**
     * 4.Zset类型操作
     * 1.增加
     * add
     * 注意:(1)与set的区别是需要带分数score
     *      (2)如果key不存在,将会被创建,value不存在也会被创建
     *      (3)如果value存在,将不能被添加
     */
    @Test
    public void addZset(){
        //(1)添加单个值
        Boolean success = redisTemplate.boundZSetOps("nameZset1").add("v1", 30);
        System.out.println("添加单个值:"+success);
        //(2)添加多个值
        ZSetOperations.TypedTuple<Object> v2 = new DefaultTypedTuple<Object>("v2", 20.0);
        ZSetOperations.TypedTuple<Object> v3 = new DefaultTypedTuple<Object>("v3", 20.0);
        HashSet<ZSetOperations.TypedTuple<Object>> typedTuples = new HashSet<ZSetOperations.TypedTuple<Object>>();
        typedTuples.add(v2);
        typedTuples.add(v3);
        Long count = redisTemplate.boundZSetOps("nameZset1").add(typedTuples);
        System.out.println("成功添加了"+count+"个值");
    }

2.删除

/**
     * 2.移除元素
     * remove
     */
    @Test
    public void removeZset(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        redisTemplate.boundZSetOps("zset1").add("e",5.2);
        redisTemplate.boundZSetOps("zset1").add("f",6.0);
        //(1)移除一个元素
        Long count = redisTemplate.boundZSetOps("zset1").remove("a");
        System.out.println("移除的元素个数:"+count);
        //(2)移除多个元素
        Long count1 = redisTemplate.boundZSetOps("zset1").remove("b", "c");
        System.out.println("移除的元素个数:"+count);
        //(3)移除指定位置的元素(注意是闭区间)
        redisTemplate.boundZSetOps("zset1").removeRange(0,-1);
        //(4)移除分数区间的元素(注意是闭区间)
        redisTemplate.boundZSetOps("zset1").removeRangeByScore(1.0,2.0);
    }

3.获取Zset集合的大小

/**
     * 2.获取Zset的大小
     * size:获取Zset的大小
     * zCard:获取Zset的大小(其实size的底层就是使用zCard)
     */
    @Test
    public void getZsetSize(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        Long size = redisTemplate.boundZSetOps("zset1").size();
        System.out.println("zset1的值个数:"+size);
        Long zCard = redisTemplate.boundZSetOps("zset1").zCard();
        System.out.println("zset1的值个数:"+zCard);
    }

4. 获取Zset集合的个数(指定score区间)

/**
     * 4.获取score在指定区间值的个数
     * count
     * 注意:区间是包括两边的,比如下面的实际上是区间[20.0,30.0]
     */
    @Test
    public void getZsetFromScoreRange(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        Long count = redisTemplate.boundZSetOps("nameZset1").count(1.0, 4.0);
        System.out.println("nameZset1中在区间10.0到30.0之间的数据个数有:"+count);

    }

5. 通过value值获取其对应分数

/**
     * 5.通过value获取score
     * score
     */
    @Test
    public void getScoreByValue(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        Double score = redisTemplate.boundZSetOps("zset1").score("d");
        System.out.println("zset1中value为d的score为:"+score);

    }

6.将score增加指定数值

/**
     * 6.对score增加指定的数值,返回增加后的值
     * incrementScore
     */
    @Test
    public void increScore(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        Double score = redisTemplate.boundZSetOps("zset1").incrementScore("a", 10.0);
        System.out.println("zset1中v1的score增加到了:"+score);
    }

7.获取Zset集合中的全部元素(包括值和score)

/**
     * 7.读取Zset集合中的全部元素元素
     * scan
     */
    @Test
    public void zsetScan(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        Cursor<ZSetOperations.TypedTuple<Object>> scan = redisTemplate.boundZSetOps("zset1").scan(ScanOptions.NONE);
        //需要迭代
        while (scan.hasNext()){
            ZSetOperations.TypedTuple<Object> next = scan.next();
            System.out.println("value:"+next.getValue()+","+"score:"+next.getScore());
        }
    }

8.获取排序后的索引(正反排序情形)

/**
     * 8.获取排序后的索引:
     * rank:在排序集中确定具有值的元素的索引,并返回其索引(从低到高),
     * reverseRank:在排序集中确定具有值的元素的索引,并返回其索引(从高到底),
     */
    @Test
    public void getZsetRank(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        //(1)正序获得索引值
        //第一步:排序(按照分数值从小到大排序)
        System.out.println("正序排列:"+redisTemplate.boundZSetOps("zset1").range(0, -1));
        //第二步:获取指定值的索引(必须在排序的情况下,另外索引值从0开始)
        System.out.println("指定值的位置:"+redisTemplate.boundZSetOps("zset1").rank("c"));
        //(2)反序获得索引值
        System.out.println("反序排列:"+redisTemplate.boundZSetOps("zset1").reverseRange(0,-1));
        System.out.println("指定值的位置:"+redisTemplate.boundZSetOps("zset1").reverseRank("c"));
    }

9.各种排序

/**
     * 8.各种排序;
     * range:按照分数由小到大排序(指定位置区间)
     * reverseRange:按照分数由大到小排序(指定位置区间)
     * rangeByScore:按照分数由小到大排序(指定分数区间)
     * reverseRangeByScore:按照分数由大到小排序(指定分数区间)
     * rangeByScoreWithScores:按照分数由小到大排序(指定分数区间),并返回排序后的结果(带分数)
     * reverseRangeByScoreWithScores:按照分数由大到小排序(指定分数区间),并返回排序后的结果(带分数)
     * rangeWithScores:按照分数从小到大排序(指定位置区间),得到的值带有score
     * reverseRangeWithScores:按照分数从大到小排序(指定分数区间),得到的值带有score
     */
    @Test
    public void getZsetRange(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a",1.0);
        redisTemplate.boundZSetOps("zset1").add("b",3.2);
        redisTemplate.boundZSetOps("zset1").add("d",5.5);
        redisTemplate.boundZSetOps("zset1").add("c",2.0);
        //(1)默认的按照分数从小到大排序(指定位置区间)
        System.out.println("按照score从小到大排序:"+redisTemplate.boundZSetOps("zset1").range(0,-1));
        //(2)按照分数从大到小排序(指定位置区间)
        System.out.println("按照score从大到小排序:"+redisTemplate.boundZSetOps("zset1").reverseRange(0,-1));
        //(3)按照分数从大到小排序(指定分数区间)
        System.out.println("按照score从大到小排序:"+redisTemplate.boundZSetOps("zset1").rangeByScore(1.0,3.0));
        //(4)按照分数从大到小排序(指定分数区间)
        System.out.println("按照score从大到小排序:"+redisTemplate.boundZSetOps("zset1").reverseRangeByScore(1.0,3.0));

        //(5)按照分数从小到大排序(指定分数区间),得到的值带有score
        Set<ZSetOperations.TypedTuple<Object>> zset1 = redisTemplate.boundZSetOps("zset1").rangeByScoreWithScores(1.0, 3.0);
        //需要迭代
        Iterator<ZSetOperations.TypedTuple<Object>> iterator1 = zset1.iterator();
        while (iterator1.hasNext()){
            ZSetOperations.TypedTuple<Object> next1 = iterator1.next();
            System.out.println("value:"+next1.getValue()+","+"score:"+next1.getScore());
        }
        System.out.println("***************************************************");

        //(6)按照分数从大到小排序(指定分数区间),得到的值带有score
        Set<ZSetOperations.TypedTuple<Object>> zset2 = redisTemplate.boundZSetOps("zset1").reverseRangeByScoreWithScores(1.0, 3.0);
        //需要迭代
        Iterator<ZSetOperations.TypedTuple<Object>> iterator2 = zset2.iterator();
        while (iterator2.hasNext()){
            ZSetOperations.TypedTuple<Object> next2 = iterator2.next();
            System.out.println("value:"+next2.getValue()+","+"score:"+next2.getScore());
        }
        System.out.println("***************************************************");

        //(7)按照分数从小到大排序(指定位置区间),得到的值带有score
        Set<ZSetOperations.TypedTuple<Object>> zset3 = redisTemplate.boundZSetOps("zset1").rangeWithScores(0, -1);
        //需要迭代
        Iterator<ZSetOperations.TypedTuple<Object>> iterator3 = zset3.iterator();
        while (iterator3.hasNext()){
            ZSetOperations.TypedTuple<Object> next3 = iterator3.next();
            System.out.println("value:"+next3.getValue()+","+"score:"+next3.getScore());
        }
        System.out.println("***************************************************");


        //(8)按照分数从大到小排序(指定分数区间),得到的值带有score
        Set<ZSetOperations.TypedTuple<Object>> zset4 = redisTemplate.boundZSetOps("zset1").reverseRangeWithScores(0, -1);
        //需要迭代
        Iterator<ZSetOperations.TypedTuple<Object>> iterator4 = zset4.iterator();
        while (iterator4.hasNext()){
            ZSetOperations.TypedTuple<Object> next4 = iterator4.next();
            System.out.println("value:"+next4.getValue()+","+"score:"+next4.getScore());
        }
        System.out.println("***************************************************");
    }

10.交集

/**
     * 10.交集
     * intersectAndStore
     */
    @Test
    public void getIntersectAndStore() {
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a", 1.0);
        redisTemplate.boundZSetOps("zset1").add("b", 3.2);
        redisTemplate.boundZSetOps("zset1").add("d", 5.5);
        redisTemplate.boundZSetOps("zset1").add("c", 2.0);

        redisTemplate.delete("zset2");
        redisTemplate.boundZSetOps("zset2").add("b", 3.2);
        redisTemplate.boundZSetOps("zset2").add("d", 5.5);
        redisTemplate.boundZSetOps("zset2").add("c", 2.0);
        redisTemplate.boundZSetOps("zset2").add("f", 4.4);

        redisTemplate.delete("zset4");
        redisTemplate.boundZSetOps("zset4").add("e", 3.2);
        redisTemplate.boundZSetOps("zset4").add("f", 5.5);
        redisTemplate.boundZSetOps("zset4").add("c", 2.0);
        redisTemplate.boundZSetOps("zset4").add("a", 4.4);

        redisTemplate.delete("zset3");

        //一:两个集合做交集
        redisTemplate.boundZSetOps("zset1").intersectAndStore("zset2", "zset3");
        Cursor<ZSetOperations.TypedTuple<Object>> scan = redisTemplate.boundZSetOps("zset3").scan(ScanOptions.NONE);
        //需要迭代
        while (scan.hasNext()) {
            ZSetOperations.TypedTuple<Object> next = scan.next();
            System.out.println("value:" + next.getValue() + "," + "score:" + next.getScore());
        }
        System.out.println("***********************************************************");

        redisTemplate.delete("zset5");
        //二:多个集合做交集
        List<Object> list = new ArrayList<Object>();
        list.add("zset2");
        list.add("zset4");
        redisTemplate.boundZSetOps("zset1").intersectAndStore(list, "zset5");
        Cursor<ZSetOperations.TypedTuple<Object>> scan1 = redisTemplate.boundZSetOps("zset5").scan(ScanOptions.NONE);
        //需要迭代
        while (scan1.hasNext()) {
            ZSetOperations.TypedTuple<Object> next1 = scan1.next();
            System.out.println("value:" + next1.getValue() + "," + "score:" + next1.getScore());
        }
    }

11.并集

/**
 * 并集
 * unionAndStore
 * 注意:对于相同的value,其score是相加
 */
@Test
public void getUnionAndStore(){
    redisTemplate.delete("zset1");
    redisTemplate.boundZSetOps("zset1").add("a",1.0);
    redisTemplate.boundZSetOps("zset1").add("b",3.2);
    redisTemplate.boundZSetOps("zset1").add("d",5.5);
    redisTemplate.boundZSetOps("zset1").add("c",2.0);

    redisTemplate.delete("zset2");
    redisTemplate.boundZSetOps("zset2").add("b",3.2);
    redisTemplate.boundZSetOps("zset2").add("d",5.5);
    redisTemplate.boundZSetOps("zset2").add("c",2.0);
    redisTemplate.boundZSetOps("zset2").add("f",4.4);

    redisTemplate.delete("zset4");
    redisTemplate.boundZSetOps("zset4").add("e",3.2);
    redisTemplate.boundZSetOps("zset4").add("f",5.5);
    redisTemplate.boundZSetOps("zset4").add("c",2.0);
    redisTemplate.boundZSetOps("zset4").add("a",4.4);

    redisTemplate.delete("zset3");

    //一:两个集合做交集
    redisTemplate.boundZSetOps("zset1").unionAndStore("zset2","zset3");
    Cursor<ZSetOperations.TypedTuple<Object>> scan = redisTemplate.boundZSetOps("zset3").scan(ScanOptions.NONE);
    //需要迭代
    while (scan.hasNext()){
        ZSetOperations.TypedTuple<Object> next = scan.next();
        System.out.println("value:"+next.getValue()+","+"score:"+next.getScore());
    }
    System.out.println("***********************************************************");

    redisTemplate.delete("zset5");
    //二:多个集合做交集
    List<Object> list = new ArrayList<Object>();
    list.add("zset2");
    list.add("zset4");
    redisTemplate.boundZSetOps("zset1").unionAndStore(list,"zset5");
    Cursor<ZSetOperations.TypedTuple<Object>> scan1 = redisTemplate.boundZSetOps("zset5").scan(ScanOptions.NONE);
    //需要迭代
    while (scan1.hasNext()){
        ZSetOperations.TypedTuple<Object> next1 = scan1.next();
        System.out.println("value:"+next1.getValue()+","+"score:"+next1.getScore());
    }

}

12.rangeByLex使用

/**
     * 12.按照字典顺序给value排序(可以参考redis命令ZRANGEBYLEX)
     * rangeByLex
     * 注意:(1)排序的value,其socre必须一致相同
     *      (2)rangeByLex的作用参考redis命令ZRANGEBYLEX
     */
    @Test
    public void zsetRangeByLex(){
        redisTemplate.delete("zset1");
        redisTemplate.boundZSetOps("zset1").add("a", 1.0);
        redisTemplate.boundZSetOps("zset1").add("f", 1.0);
        redisTemplate.boundZSetOps("zset1").add("s", 1.0);
        redisTemplate.boundZSetOps("zset1").add("d", 1.0);
        redisTemplate.boundZSetOps("zset1").add("b", 1.0);
        redisTemplate.boundZSetOps("zset1").add("c", 1.0);

        RedisZSetCommands.Range range = new RedisZSetCommands.Range();
        range.gt("a"); //从a开始,但是不包括a
        range.lt("s"); //s结束,但是不包括s

        System.out.println(redisTemplate.boundZSetOps("zset1").rangeByLex(range));  //获得所有元素与ZSET辞典编纂的排序键和一个值

        RedisZSetCommands.Limit limit = new RedisZSetCommands.Limit();
        limit.offset(0); //从坐标0开始
        limit.count(3); //取出3个
        System.out.println(redisTemplate.boundZSetOps("zset1").rangeByLex(range, limit)); //获得所有元素与ZSET辞典编纂的排序键和一个值,限制个数
    }

二、总结

以上便是Zset的全部API操作,由于事务操作较为复杂,这里先暂时不讨论。如果上面使用过程中出了任何问题,望指出。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值