In my application I need have a set of values and I need to check how many of these values are present in a set in Redis.
Just to make it simple, What I want to do is something like :
> 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.
Since I can not give multiple parameters for SISMEMBER
, I might have to multiple redis call which is very time consuming.
I was thinking about alternatives like pipelining
but then I thought this will be a good (hacky) way of achieving it :
> 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 page says the following :
Available since 2.0.0.
Time complexity: O(N) where N is the number of fields being requested.
Which is really good when compared to making multiples calls for SADD
, But I am really not sure If I am 100% correct and I also don't know if there is any serious drawback of using hmget
this way.
So I just wanted to the drawbacks of using hmget
this way and any better approaches to solve this.
This is certainly a valid solution, although a little wasteful as you'll be maintaining a bunch of true
values - a RAM overhead. FYI, Redis' Sets are implemented internally using the same hash table structs as Hashes are, so you're not that far off :)
While there is no variadic form of SISMEMBER
, it as an easily scriptable flow with Lua so you may want to consider that as well. For example something like the following:
local r = {}
for _, m in pairs(ARGV) do
r[#r+1] = redis.call('SISMEMBER', KEYS[1], m)
end
return r
Following @itamar 's answer, I was able to do this using lua script.
I used the following script:
local r = {}
for i, m in pairs(KEYS) do
r[i] = redis.call('SISMEMBER',ARGV[1],m)
end
return r
May be this will be useful for someone in future, so just writing how to call this script from 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"));
prints the following :
[0, 0, 1, 1, 1]
EDIT I am not sure everybody is saying that mySet
is KEYS and list
is ARGV, but in SPRING DATA REDIS
, execute
function is defined in the following way :
public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) {
return this.scriptExecutor.execute(script, keys, args);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With