Jedis 操作有序集合(Sorted Set)

Redis 有序集合(Sorted Set)和集合(Set)一样,也是 string 类型元素的集合,并且集合元素不允许重复。Redis 有序集合中每个元素都会关联一个 double 类型的分数(注意:分数允许重复),Redis 有序集合将按分数(score)进行排序。本文将介绍怎样通过 jedis 库操作 Redis 的 Sorted Set 数据类型。

添加成员

向有序集合添加一个或多个成员,方法定义如下:

  • Long zadd(String key, double score, String member)  将具有指定分数的成员添加到存储在key的有序集合中。

  • Long zadd(String key, double score, String member, ZAddParams params) 使用指定的 ZAddParams 参数将具有指定分数的成员添加到存储在key的有序集合中。

  • Long zadd(String key, Map<String,Double> scoreMembers) 批量将成员和分数添加到有序集合。

  • Long zadd(String key, Map<String,Double> scoreMembers, ZAddParams params) 使用指定的 ZAddParams 参数批量将成员和分数添加到有序集合。

示例:

// 向 mykey 存储的有序集合添加一个 member1 成员
jedis.zadd("mykey", 10, "member1");

// 向 mykey 存储的有序集合批量添加成员
Map<String,Double> map = new HashMap<>();
map.put("membe2", 20D);
map.put("membe3", 30D);
jedis.zadd("mykey", map);

// 使用 ZAddParams 参数调用 zadd 命令
ZAddParams params = new ZAddParams();
// 仅当键不存在时才设置键
params.nx();
jedis.zadd("mykey", 40, "member4", params);

成员个数

用来获取有序集合中成员个数,方法定义如下:

  • Long zcard(String key)

示例:

// 准备数据
jedis.zadd("mykey", 10, "member1");
jedis.zadd("mykey", 20, "member2");
jedis.zadd("mykey", 30, "member3");
jedis.zadd("mykey", 40, "member4");

// 获取集合成元素
Long size = jedis.zcard("mykey");
System.out.println("size=" + size); // size=4

移除成员

从有序集合中移除一个或多个成员,方法定义如下:

  • Long zrem(String key, String... members)  从存储在key的有序集值中删除指定的成员。

  • Long zremrangeByLex(String key, String min, String max)  根据字典顺序排序,删除排序后的有序集合中 min 到 max 范围中的成员

  • Long zremrangeByRank(String key, long start, long stop)  根据成员在有序集合中的索引进行删除,删除位于 start 到 stop 索引之间的成员

  • Long zremrangeByScore(String key, double min, double max)  根据分值范围删除成员,删除排序后的有序集合中所有分值在 min 和 max 之间的成员(包括分值等于 min 或 max 的元素)。

  • Long zremrangeByScore(String key, String min, String max)

示例:

// 准备数据
jedis.zadd("mykey", 10, "c");
jedis.zadd("mykey", 20, "c++");
jedis.zadd("mykey", 30, "php");
jedis.zadd("mykey", 40, "java");
jedis.zadd("mykey", 50, "python");
jedis.zadd("mykey", 60, "javascript");
jedis.zadd("mykey", 70, "erlang");

// 移除成员 member2 和 member3
jedis.zrem("mykey", "member2", "member3");
Set<String> result = jedis.zrange("mykey", 0, -1);
System.out.println("result=" + Arrays.toString(result.toArray()));
// result=[c, c++, php, java, python, javascript, erlang]

// 根据索引移除第一个成员
jedis.zremrangeByRank("mykey", 0, 0);
result = jedis.zrange("mykey", 0, -1);
System.out.println("result=" + Arrays.toString(result.toArray()));
// result=[c++, php, java, python, javascript, erlang]

// 移除分值在 30~40 之间的成员
jedis.zremrangeByScore("mykey", 30, 40);
result = jedis.zrange("mykey", 0, -1);
System.out.println("result=" + Arrays.toString(result.toArray()));
// result=[c++, python, javascript, erlang]

// 根据数据字典移除成员
jedis.zremrangeByLex("mykey", "[erlang", "[python");
result = jedis.zrange("mykey", 0, -1);
System.out.println("result=" + Arrays.toString(result.toArray()));
// result=[c++]

成员分值

用来获取有序集合中指定成员的分值,方法定义如下:

  • Double zscore(String key, String member)

示例:

// 准备数据
jedis.zadd("mykey", 10, "member1");
jedis.zadd("mykey", 20, "member2");
jedis.zadd("mykey", 30, "member3");
jedis.zadd("mykey", 40, "member4");

// 获取 member3 成员的分值
Double score = jedis.zscore("mykey", "member3");
System.out.println("score=" + score); // score=30.0

成员个数

计算指定分值范围内部的成员个数,方法定义如下:

  • Long zcount(String key, double min, double max)

  • Long zcount(String key, String min, String max)

示例:

// 准备数据
jedis.zadd("mykey", 10, "member1");
jedis.zadd("mykey", 20, "member2");
jedis.zadd("mykey", 30, "member3");
jedis.zadd("mykey", 40, "member4");

// 获取分值在 20 ~ 30 之间的成员个数
Long count = jedis.zcount("mykey", 20, 30);
System.out.println("count=" + count); // count=2

上面介绍了根据分值范围计算个数,我们还可以计算有序集合中指定字典区间内成员数量,方法定义如下:

  • Long zlexcount(String key, String min, String max)

示例:

// 准备数据
jedis.zadd("mykey", 10, "a");
jedis.zadd("mykey", 20, "b");
jedis.zadd("mykey", 30, "c");
jedis.zadd("mykey", 40, "d");

// 计算 mykey 集合中指定字典区间内的成员数量
Long count = jedis.zlexcount("mykey", "[b", "[c");
System.out.println("count=" + count); // count=2

分值自增

用来对指定成员的分值进行自增操作,方法定义如下:

  • Double zincrby(String key, double increment, String member)  如果成员已经存在于有序集合中,则将增量值加到成员的分值上,并相应地更新该成员在有序集合中的位置。

  • Double zincrby(String key, double increment, String member, ZIncrByParams params)

示例:

// 准备数据
jedis.zadd("mykey", 10, "member1");

// 对成员 member1 的分值加 15
Double score = jedis.zincrby("mykey", 15, "member1");
System.out.println("score=" + score); // score=25.0

score = jedis.zscore("mykey", "member1");
System.out.println("score=" + score); // score=25.0

成员索引(递增)

用来获取指定成员的索引,方法定义如下:

  • Long zrank(String key, String member)  返回成员在有序集合中的索引,分值按照从低到高排序。

示例:

// 准备数据
jedis.zadd("mykey", 10, "member1");
jedis.zadd("mykey", 20, "member2");
jedis.zadd("mykey", 30, "member3");
jedis.zadd("mykey", 40, "member4");

// 获取 member2 成员在有序集合中的索引
Long index = jedis.zrank("mykey", "member2");
System.out.println("index=" + index); // index=1

成员索引(递减)

用来获取有序集合中指定成员的索引,有序集成员按分数值递减(从大到小)排序,方法定义如下:

  • Long zrevrank(String key, String member)  返回成员在有序集合中的索引,分数从高到低排序。

示例:

// 准备数据
jedis.zadd("mykey", 10, "member1");
jedis.zadd("mykey", 20, "member2");
jedis.zadd("mykey", 30, "member3");
jedis.zadd("mykey", 40, "member4");

// 返回 mykey 有序集合中指定成员的排名
// 有序集成员按分数值递减 (从大到小) 排序
Long index = jedis.zrevrank("mykey", "member2");
System.out.println("index=" + index); // index=2

计算交集

用来计算给定的一个或多个有序集合的交集并将结果集存储在新的有序集合 dstkey 中,方法定义如下:

  • Long zinterstore(String dstkey, String... sets)  创建一个由键 k1 到 kN 给定的 N 个有序集合的交集,并将其存储在 dstkey 有序集合。

  • Long zinterstore(String dstkey, ZParams params, String... sets)

示例:

// 准备数据
jedis.zadd("mykey1", 10, "member1");
jedis.zadd("mykey1", 20, "member2");
jedis.zadd("mykey1", 30, "member3");

jedis.zadd("mykey2", 20, "member2");
jedis.zadd("mykey2", 30, "member3");
jedis.zadd("mykey2", 40, "member4");

// 计算 mykey1 和 mykey2 有序集合的交集,并将结果存储在 target 有序集合
Long result = jedis.zinterstore("target", "mykey1", "mykey2");
System.out.println("result=" + result); // result=2

// 根据索引获取集合成员
Set<String> keys = jedis.zrange("target", 0, result);
System.out.println("keys=" + Arrays.toString(keys.toArray()));
// keys=[member2, member3]

计算并集

用来计算给定的一个或多个有序集合的并集,并将结果存储在新的 dstkey 有序集合中,方法定义如下:

  • Long zunionstore(String dstkey, String... sets)  创建一个由键 k1 到 kN 给定的 N 个有序集合的并集,并将结果存储在 dstkey 有序集合中。

  • Long zunionstore(String dstkey, ZParams params, String... sets)

示例:

// 准备数据
jedis.zadd("mykey1", 10, "member1");
jedis.zadd("mykey1", 20, "member2");
jedis.zadd("mykey1", 30, "member3");

jedis.zadd("mykey2", 20, "member2");
jedis.zadd("mykey2", 30, "member3");
jedis.zadd("mykey2", 40, "member4");

// 计算 mykey1 和 mykey2 有序集合的并集,并将结果存储在 target 有序集合
Long result = jedis.zunionstore("target", "mykey1", "mykey2");
System.out.println("result=" + result); // result=4

// 根据索引获取集合成员
Set<String> keys = jedis.zrange("target", 0, result);
System.out.println("keys=" + Arrays.toString(keys.toArray()));
// keys=[member1, member2, member4, member3]

迭代成员

用来迭代有序集合中的成员(包括成员和分值),方法定义如下:

  • ScanResult<Tuple> zscan(String key, String cursor)

  • ScanResult<Tuple> zscan(String key, String cursor, ScanParams params)

示例:

// 准备数据
jedis.zadd("mykey", 10, "java");
jedis.zadd("mykey", 20, "php");
jedis.zadd("mykey", 30, "javascript");
jedis.zadd("mykey", 40, "vbscript");

// 扫描有序集合 mykey,输出所有以 “script” 字符结尾的成员
ScanParams scanParams = new ScanParams();
scanParams.match("*script");
ScanResult<Tuple> scanResult = jedis.zscan("mykey", "0", scanParams);
for(Tuple tuple : scanResult.getResult()) {
   System.out.println(tuple.getElement() + " => " + tuple.getScore());
   // 结果:
   // javascript => 30.0
   // vbscript => 40.0
}

成员区间

用来根据指定的区间(如:分值区间、索引区间等)获取区间中的成员信息,方法定义如下:

  • Set<String> zrange(String key, long start, long stop)

  • Set<String> zrangeByLex(String key, String min, String max)

  • Set<String> zrangeByLex(String key, String min, String max, int offset, int count)

  • Set<String> zrangeByScore(String key, double min, double max)  返回 key 有序集合中分数在 min 和 max 之间的所有成员(包括分值等于 min 或 max 的元素)

  • Set<String> zrangeByScore(String key, double min, double max, int offset, int count)  返回 key 有序集合中分数在 min 和 max 之间的所有成员中偏移量从 offset 开始的 count 个成员

  • Set<String> zrangeByScore(String key, String min, String max)

  • Set<String> zrangeByScore(String key, String min, String max, int offset, int count)

  • Set<Tuple> zrangeByScoreWithScores(String key, double min, double max)  返回 key 有序集合中分数在 min 和 max 之间的所有成员(包括分值等于 min 或 max 的元素),注意:返回的数据包含成员键和分值

  • Set<Tuple> zrangeByScoreWithScores(String key, double min, double max, int offset, int count)

  • Set<Tuple> zrangeByScoreWithScores(String key, String min, String max)

  • Set<Tuple> zrangeByScoreWithScores(String key, String min, String max, int offset, int count)

  • Set<Tuple> zrangeWithScores(String key, long start, long stop)

示例:

// 准备数据
jedis.zadd("mykey", 10, "java");
jedis.zadd("mykey", 20, "php");
jedis.zadd("mykey", 30, "javascript");
jedis.zadd("mykey", 40, "vbscript");

// 获取 mykey 有序集合索引 0~1 之间的成员(分值从低到高)
Set<String> keys = jedis.zrange("mykey", 0, 1);
System.out.println("keys=" + Arrays.toString(keys.toArray())); // keys=[java, php]

// 获取 mykey 有序集合索引 0~1 之间的成员(分值从高到低)
keys = jedis.zrevrange("mykey", 0, 1);
System.out.println("keys=" + Arrays.toString(keys.toArray())); // keys=[vbscript, javascript]

// 通过字典区间返回有序集合的成员
// 从 [java 元素开始,到 [php 元素结束
keys = jedis.zrangeByLex("mykey", "[java", "[php");
System.out.println("keys=" + Arrays.toString(keys.toArray())); // keys=[java, php, javascript]

// 获取所有元素
keys = jedis.zrangeByLex("mykey", "-", "+");
System.out.println("keys=" + Arrays.toString(keys.toArray())); // keys=[java, php, javascript, vbscript]

// 获取 mykey 有序集合中分值位于 20~30 之间的元素,按照分值从低到高排序
keys = jedis.zrangeByScore("mykey", 20, 30);
System.out.println("keys=" + Arrays.toString(keys.toArray())); // keys=[php, javascript]

// 获取 mykey 有序集合中分值位于 20~30 之间的元素,按照分值从高到低排序
keys = jedis.zrevrangeByScore("mykey", 30, 20);
System.out.println("keys=" + Arrays.toString(keys.toArray())); // keys=[javascript, php]
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号