在我的应用程序中,我需要一组值,我需要检查Redis 中设置中存在多少这些值。
为了简单起见,我想做的是:
> Sadd myset field1
(integer) 1
> Sadd myset field2
(integer) 1
> Sadd myset field4
(integer) 1
> Sismember myset field1 field4 // which is not possible as of now.
由于我无法为SISMEMBER
提供多个参数,因此我可能需要进行多次redis调用,这非常耗时。
我在考虑像pipelining
这样的替代品,但后来我认为这将是一种很好的(hacky)方法来实现它:
> Hset myhash field1 "true"
(integer) 0
> Hset myhash field2 "true"
(integer) 0
> Hset myhash field4 "true"
(integer) 1
> Hmget myhash field1 field2 field3
1) "true"
2) "true"
3) (nil)
> Hmget myhash field1 field2 field3 field4
1) "true"
2) "true"
3) (nil)
4) "true"
Redis
HMGET页面说明如下:
自2.0.0起可用。
时间复杂度:O(N)其中N是请求的字段数。
与制作SADD
的倍数调用相比,这真的很好,但我真的不确定如果我100%正确,我也不知道使用{{1}是否有任何严重的缺点}} 这条路。
所以我只是想用这种方式使用hmget
的缺点以及任何更好的方法来解决这个问题。
答案 0 :(得分:1)
这当然是一个有效的解决方案,虽然有点浪费,因为你将维护一堆true
值 - 一个RAM开销。仅供参考,Redis'集合使用与Hashes相同的哈希表结构在内部实现,所以你不是那么远:)
虽然没有SISMEMBER
的可变形式,但它是一个易于编写流程的Lua,因此您可能也想考虑这一点。例如以下内容:
local r = {}
for _, m in pairs(ARGV) do
r[#r+1] = redis.call('SISMEMBER', KEYS[1], m)
end
return r
答案 1 :(得分:1)
根据@itamar的回答,我能够使用lua脚本执行此操作。
我使用了以下脚本:
local r = {}
for i, m in pairs(KEYS) do
r[i] = redis.call('SISMEMBER',ARGV[1],m)
end
return r
这可能会对将来的某些人有用,所以只需编写如何从java
(Spring Data Redis 1.5.0
& jedis 2.6.2
)
redisTemplate.opsForSet().add("mySet","3");
redisTemplate.opsForSet().add("mySet","4");
redisTemplate.opsForSet().add("mySet","35");
redisTemplate.opsForSet().add("mySet", "6");
List<String> list = new LinkedList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("35");
list.add("6");
System.out.println(redisTemplate.execute(script, list,"mySet"));
打印以下内容:
[0, 0, 1, 1, 1]
编辑我不确定每个人都说mySet
是KEYS且list
是ARGV,但在SPRING DATA REDIS
中,execute
函数是按以下方式定义:
public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) {
return this.scriptExecutor.execute(script, keys, args);
}
答案 2 :(得分:0)
使用Redisson框架在Java上执行此操作更容易:
RSet<String> set = redisson.getSet("mySet");
// uses lua-script under the hood
if (set.containsAll(Arrays.asList("obj1", "obj2", "obj3", "obj4"))) {
// ...
}
答案 3 :(得分:0)
从 Redis 6.2 开始,您可以使用 SMISMEMBER 命令检查给定集合是否存在多个元素。它将以与请求相同的顺序返回给定元素的数组回复。您可以在客户端获取数组的总和,以获取集合中存在多少这些值。
redis> SADD myset foo bar zet que
(integer) 4
redis> SMISMEMBER myset foo bar not
1) (integer) 1
2) (integer) 1
3) (integer) 0