Karthik Karthik - 2 months ago 36
Java Question

Redis - Alternative to check existence of multiple values in a set

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.

Answer

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