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

Posted 晓锋残月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了探索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以上是关于探索redis设计与实现1:SpringDataRedis常用API——ZSet的主要内容,如果未能解决你的问题,请参考以下文章

Redis技术探索「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移Redis数据实战指南(离线同步数据)

Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

Redis 技术探索「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(数据检查对比)

opentsdb探索之路——部分设计与实现

Redis 技术探索「数据迁移实战」手把手教你如何实现在线+离线模式进行迁移Redis数据实战指南(离线同步数据)

Redis技术探索「数据迁移实战」手把手教你如何实现在线+离线模式进行迁移Redis数据实战指南(在线同步数据)