Spring Data Redis 教程

ReactiveZSetOperations 操作接口

Spring Data Redis 中,ZSet 类型的响应式接口为 ReactiveZSetOperations,该接口定义的方法和 ZSetOperations、BoundZSetOperations 接口定义的方法非常类似。

我们可以通过 ReactiveRedisTemplate 的 opsForZSet() 方法获取获取,代码如下:

ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();

添加元素

  • reactor.core.publisher.Mono<Boolean> add(K key, V value, double score) 将 value 添加到 key 对应的 zset 集合,如果它已经存在则更新其 score。

  • reactor.core.publisher.Mono<Long> addAll(K key, Collection<? extends ZSetOperations.TypedTuple<V>> tuples) 将 tuples 添加到 key 的 zset 集合中,如果它已经存在则更新它们的分数。

示例:

@Test
public void add() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加一个元素
    ops.add("zset-key", "value1", 10)
            .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) {
                    if(aBoolean) {
                        queue.add("成功添加元素");
                    } else {
                        queue.add("添加元素失败");
                    }
                }
            });
    System.out.println(queue.take());

    // 添加多个元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("value2", 20D),
            new DefaultTypedTuple<String>("value3", 30D),
            new DefaultTypedTuple<String>("value4", 40D)
        )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功添加" + aLong + "个元素");
        }
    });

    // 输出所有元素
    ops.scan("zset-key").collectList().subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() {
        @Override
        public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) {
            for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
                System.out.println("value=" + typedTuple.getValue() +
                        ", score=" + typedTuple.getScore());
            }
            queue.add("元素个数" + typedTuples.size());
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功添加元素
成功添加3个元素
value=value1, score=10.0
value=value2, score=20.0
value=value3, score=30.0
value=value4, score=40.0
元素个数4

获取集合大小

  • reactor.core.publisher.Mono<Long> count(K key, org.springframework.data.domain.Range<Double> range) 计算 key 对应的 zset 集合中的元素个数,元素的分数在最小值(min)和最大值(max)之间。

示例:

@Test
public void count() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加多个元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 20D),
            new DefaultTypedTuple<String>("value3", 30D),
            new DefaultTypedTuple<String>("value4", 40D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    ops.count("zset-key",
            Range.of(Range.Bound.inclusive(20D), Range.Bound.inclusive(30D)))
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) {
                    queue.add("有" + aLong + "个元素");
                }
            });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功添加4个元素
有2个元素

删除指定键

  • reactor.core.publisher.Mono<Boolean> delete(K key) 移除给定的 key

示例:

@Test
public void delete() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加多个元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 20D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 删除 zset-key
    ops.delete("zset-key").subscribe(new Consumer<Boolean>() {
        @Override
        public void accept(Boolean aBoolean) {
            if(aBoolean) {
                queue.add("删除 zset-key 成功");
            } else {
                queue.add("删除 zset-key 失败");
            }
        }
    });
    System.out.println(queue.take());

    // 输出所有元素
    ops.scan("zset-key").collectList().subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() {
        @Override
        public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) {
            for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
                System.out.println("value=" + typedTuple.getValue() +
                        ", score=" + typedTuple.getScore());
            }
            queue.add("元素个数" + typedTuples.size());
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功添加2个元素
删除 zset-key 成功
元素个数0

分数递增

  • reactor.core.publisher.Mono<Double> incrementScore(K key, V value, double delta) 按增量(delta)递增 zset 集合中值等于 value 的元素的分数。

示例:

@Test
public void incrementScore() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加一个元素
    ops.add("zset-key", "value1", 10)
            .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) {
                    if(aBoolean) {
                        queue.add("成功添加元素");
                    } else {
                        queue.add("添加元素失败");
                    }
                }
            });
    System.out.println(queue.take());

    // 将 zset-key 集合中 value1 的分数添加 100
    ops.incrementScore("zset-key", "value1", 100)
        .subscribe(new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                queue.add("修改 zset-key 的 value1 分数成功,最新分数:" + aDouble);
            }
        });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功添加元素
修改 zset-key 的 value1 分数成功,最新分数:110.0

计算集合交集

  • reactor.core.publisher.Mono<Long> intersectAndStore(K key, Collection<K> otherKeys, K destKey) 计算 key 和 otherKeys 对应集合的交集,并将结果存储到 destKey 集合中。

  • reactor.core.publisher.Mono<Long> intersectAndStore(K key, K otherKey, K destKey) 计算 key 和 otherKey 对应集合的交集,并将结果存储到 destKey 集合中。

示例:

@Test
public void intersectAndStore() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key1", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 20D),
            new DefaultTypedTuple<String>("value3", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key1添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 添加元素
    ops.addAll("zset-key2", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 20D),
            new DefaultTypedTuple<String>("value4", 40D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key2添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 添加元素
    ops.addAll("zset-key3", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 20D),
            new DefaultTypedTuple<String>("value5", 40D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key3添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 计算三个key的交集,将结果存储到 destKey 集合
    ops.intersectAndStore("zset-key1", Arrays.asList("zset-key2", "zset-key3"),
            "destKey").subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("结果大小:" + aLong);
        }
    });
    System.out.println(queue.take());

    // 验证 destKey
    ops.scan("destKey").collectList().subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() {
        @Override
        public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) {
            for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
                System.out.println("value=" + typedTuple.getValue() +
                        ", score=" + typedTuple.getScore());
            }
            queue.add("元素个数" + typedTuples.size());
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功向zset-key1添加3个元素
成功向zset-key2添加3个元素
成功向zset-key3添加3个元素
结果大小:2
value=value1, score=30.0
value=value2, score=60.0
元素个数2

从上面输出结果可知,value1 和 value2 的分数是 zset-key1、zset-key2 和 zset-key3 元素的总和。

范围操作(正序)

  • reactor.core.publisher.Flux<V> range(K key, org.springframework.data.domain.Range<Long> range) 从 zset 集合中获取开始(start)和结束(end)之间的元素。

示例:

@Test
public void range() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 40D),
            new DefaultTypedTuple<String>("value3", 20D),
            new DefaultTypedTuple<String>("value4", 50D),
            new DefaultTypedTuple<String>("value5", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 上面元素添加到 zset 后,顺序为:
    // value1,value3,value5,value2,value4
    // 根据 zset 中元素排序后的顺序获取下标在 0 和 2 之间的元素
    Range<Long> range = Range.of(Range.Bound.inclusive(0L), Range.Bound.inclusive(2L));
    ops.range("zset-key", range).collectList()
        .subscribe(new Consumer<List<String>>() {
            @Override
            public void accept(List<String> strings) {
                for(String str : strings) {
                    System.out.println(str);
                }
            }
        });
}

运行示例,输出结果如下:

成功向zset-key添加5个元素
value1
value3
value5
  • reactor.core.publisher.Flux<V> rangeByLex(K key, org.springframework.data.domain.Range<String> range) 从 zset 中获取所有具有字典顺序的元素,其值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间。

  • reactor.core.publisher.Flux<V> rangeByLex(K key, org.springframework.data.domain.Range<String> range, RedisZSetCommands.Limit limit) 从 zset 中获取所有具有字典顺序的元素的 n 个元素,其中 n = RedisZSetCommands.Limit.getCount(),从 RedisZSetCommands.Limit.getOffset() 开始,值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间。

示例:

@Test
public void rangeByLex() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("Admin", 10D),
            new DefaultTypedTuple<String>("Back", 40D),
            new DefaultTypedTuple<String>("Control", 20D),
            new DefaultTypedTuple<String>("Date", 50D),
            new DefaultTypedTuple<String>("Edit", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 使用字典顺序检索 range.getLowerBound() 到 range.getUpperBound() 之间的元素
    Range<String> range = Range.of(Range.Bound.inclusive("B"), Range.Bound.inclusive("D"));
    System.out.println("getLowerBound()=" + range.getLowerBound());
    System.out.println("getUpperBound()=" + range.getUpperBound());
    ops.rangeByLex("zset-key", range).collectList()
            .subscribe(new Consumer<List<String>>() {
                @Override
                public void accept(List<String> strings) {
                    for(String str : strings) {
                        System.out.println(str);
                    }
                    queue.add(range.getLowerBound() + "~" + range.getUpperBound() +
                            "之间有" + strings.size() + "个元素");
                }
            });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功向zset-key添加5个元素
getLowerBound()=B
getUpperBound()=D
Control
B~D之间有1个元素
  • reactor.core.publisher.Flux<V> rangeByScore(K key, org.springframework.data.domain.Range<Double> range) 从 zset 中获取分数在最小值(min)和最大值(max)之间的元素。

  • reactor.core.publisher.Flux<V> rangeByScore(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 从排序的集合中获取从开始到结束的元素,其中得分介于最小和最大之间。

  • reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> rangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range) 从 zset 中获取分数介于最小值(min)和最大值(max)之间的 RedisZSetCommands.Tuples 集合。

  • reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> rangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 从开始到结束的范围内获取一组 Redis ZSet Commands.Tuples,其中分数在最小值和最大值之间。

  • reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> rangeWithScores(K key, org.springframework.data.domain.Range<Long> range) 从 zset 集中获取开始和结束之间的一组 RedisZSetCommands.Tuples。

示例:

@Test
public void rangeByScore() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("Admin", 10D),
            new DefaultTypedTuple<String>("Back", 40D),
            new DefaultTypedTuple<String>("Control", 20D),
            new DefaultTypedTuple<String>("Date", 50D),
            new DefaultTypedTuple<String>("Edit", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    Range<Double> range = Range.of(Range.Bound.inclusive(20D), Range.Bound.inclusive(30D));
    ops.rangeByScore("zset-key", range).collectList()
            .subscribe(new Consumer<List<String>>() {
                @Override
                public void accept(List<String> strings) {
                    for(String str : strings) {
                        System.out.println(str);
                    }
                    queue.add(range.getLowerBound() + "~" + range.getUpperBound() +
                            "分数之间存在" + strings.size() + "个元素");
                }
            });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功向zset-key添加5个元素
Control
Edit
20.0~30.0分数之间存在2个元素

返回值的索引

  • reactor.core.publisher.Mono<Long> rank(K key, Object o) 确定指定值在 zset 集中的索引。

  • reactor.core.publisher.Mono<Long> reverseRank(K key, Object o) 当得分从高到低时,确定排序集中具有值的元素的索引。

示例:

@Test
public void rank() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("Admin", 10D),
            new DefaultTypedTuple<String>("Back", 40D),
            new DefaultTypedTuple<String>("Control", 20D),
            new DefaultTypedTuple<String>("Date", 50D),
            new DefaultTypedTuple<String>("Edit", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 查找 Back 元素在 zset-key 中的索引
    ops.rank("zset-key", "Back").subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("Back 的索引位置:" + aLong);
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

Back 的索引位置:3

移除元素

  • reactor.core.publisher.Mono<Long> remove(K key, Object... values) 从 zset 集中删除值。

  • reactor.core.publisher.Mono<Long> removeRange(K key, org.springframework.data.domain.Range<Long> range) 从 key 对应的 zset 集中删除开始和结束之间范围内的元素。

  • reactor.core.publisher.Mono<Long> removeRangeByScore(K key, org.springframework.data.domain.Range<Double> range) 从 key 对应的 zset 集中删除分数在 min 和 max 之间的元素。

示例:

@Test
public void remove() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("Admin", 10D),
            new DefaultTypedTuple<String>("Back", 40D),
            new DefaultTypedTuple<String>("Control", 20D),
            new DefaultTypedTuple<String>("Date", 50D),
            new DefaultTypedTuple<String>("Edit", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 删除元素 Date 和 Edit 元素
    ops.remove("zset-key", "Date", "Edit").subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功删除" + aLong + "元素");
        }
    });
    System.out.println(queue.take());

    // 输出result集合
    ops.scan("zset-key").collectList()
            .subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() {
                @Override
                public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) {
                    for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
                        System.out.println("value=" + typedTuple.getValue() +
                                ", score=" + typedTuple.getScore());
                    }
                    queue.add("zset-key 集合中有" + typedTuples.size() + "个元素");
                }
            });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功向zset-key添加5个元素
成功删除2元素
value=Admin, score=10.0
value=Control, score=20.0
value=Back, score=40.0
zset-key 集合中有3个元素

范围操作(逆序)

  • reactor.core.publisher.Flux<V> reverseRange(K key, org.springframework.data.domain.Range<Long> range) 按从高到低的顺序排列 zset 集合中的元素,然后获取开始到结束之间的元素。

  • reactor.core.publisher.Flux<V> reverseRangeByLex(K key, org.springframework.data.domain.Range<String> range) 从 ZSET 中获取所有具有反向字典顺序的元素,其值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间。

  • reactor.core.publisher.Flux<V> reverseRangeByLex(K key, org.springframework.data.domain.Range<String> range, RedisZSetCommands.Limit limit) 从 key 的 ZSET 反向字典排序中获取 n 个元素,从 RedisZSetCommands.Limit.getOffset() 开始,值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间,其中 n = RedisZSetCommands.Limit.getCount()。

  • reactor.core.publisher.Flux<V> reverseRangeByScore(K key, org.springframework.data.domain.Range<Double> range) 按从高到低顺序排序 zset 集合中的元素,然后获取分数在最小值和最大值之间的元素。

  • reactor.core.publisher.Flux<V> reverseRangeByScore(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 按从高到低顺序排序 zset 集合中的元素,然后获取分数在最小值和最大值之间的 limit 个元素。

  • reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> reverseRangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range) 从由高到低排序的 zset 排序集中获取分数在最小值和最大值之间的一组 RedisZSetCommands.Tuple。

  • reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> reverseRangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 获取从开始到结束范围内的 RedisZSetCommands.Tuple 集,其中分数介于排序集高 -> 低的排序集的最小值和最大值之间。

  • reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> reverseRangeWithScores(K key, org.springframework.data.domain.Range<Long> range) 从由高到低排序的有序集合中,从开始到结束的范围内获取一组 RedisZSetCommands.Tuples。

示例:

@Test
public void reverseRange() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key", Arrays.asList(
            new DefaultTypedTuple<String>("Admin", 10D),
            new DefaultTypedTuple<String>("Back", 40D),
            new DefaultTypedTuple<String>("Control", 20D),
            new DefaultTypedTuple<String>("Date", 50D),
            new DefaultTypedTuple<String>("Edit", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 逆序获取范围内的元素(从高到低)获取下标 0 ~ 3 之间的元素
    Range<Long> range = Range.of(Range.Bound.inclusive(0L), Range.Bound.inclusive(3L));
    ops.reverseRange("zset-key", range).collectList()
        .subscribe(new Consumer<List<String>>() {
            @Override
            public void accept(List<String> strings) {
                for(String str : strings) {
                    System.out.println(str);
                }
                queue.add(range.getLowerBound() + "~" + range.getUpperBound() +
                        "之间存在" + strings.size() + "个元素");
            }
        });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功向zset-key添加5个元素
Date
Back
Edit
Control
0~3之间存在4个元素

获取分数(score)

  • reactor.core.publisher.Mono<Double> score(K key, Object o) 使用 key 从 zset 集中获取具有值的元素的分数(score)。

获取集合大小

  • reactor.core.publisher.Mono<Long> size(K key) 返回给定 key 对应 zset 集合元素的个数。

合并集合

  • reactor.core.publisher.Mono<Long> unionAndStore(K key, Collection<K> otherKeys, K destKey) 合并 key 和 otherKeys 集合,并且将合并结果存储在目标 destKey 集合中。

  • reactor.core.publisher.Mono<Long> unionAndStore(K key, K otherKey, K destKey) 合并 key 和 otherKey 集合,并且将合并结果存储在目标 destKey 集合中。

示例:

@Test
public void unionAndStore() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
    // 添加元素
    ops.addAll("zset-key1", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 20D),
            new DefaultTypedTuple<String>("value3", 30D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key1添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 添加元素
    ops.addAll("zset-key2", Arrays.asList(
            new DefaultTypedTuple<String>("value1", 10D),
            new DefaultTypedTuple<String>("value2", 20D),
            new DefaultTypedTuple<String>("value4", 40D)
    )).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("成功向zset-key2添加" + aLong + "个元素");
        }
    });
    System.out.println(queue.take());

    // 合并元素
    ops.unionAndStore("zset-key1", "zset-key2", "result")
        .subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) {
                queue.add("合并元素成功,元素个数:" + aLong);
            }
        });
    System.out.println(queue.take());

    // 输出result集合
    ops.scan("result").collectList()
            .subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() {
                @Override
                public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) {
                    for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
                        System.out.println("value=" + typedTuple.getValue() +
                                ", score=" + typedTuple.getScore());
                    }
                    queue.add("result 集合中有" + typedTuples.size() + "个元素");
                }
            });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

成功向zset-key1添加3个元素
成功向zset-key2添加3个元素
合并元素成功,元素个数:4
value=value1, score=20.0
value=value3, score=30.0
value=value2, score=40.0
value=value4, score=40.0
result 集合中有4个元素
说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号