0

I'm trying to use Redis sorted set as my secondary index while the actual data is stored on AWS S3.

Let's say if I want to support a condition like Name!= 'uma' is there anyway to achieve that using the inbuilt pattern matching?

For example, Let's i have below as my sorted set key

ZADD mykey 0 uma:7000
ZADD mykey 0 umesh:7001
ZADD mykey 0 mahes:7002

Can I do something like ZSCAN mykey 0 match !uma?

I don't want to get all data in-memory and apply != in the application layer.

Thanks in advance

Umamaheswaran
  • 3,690
  • 3
  • 29
  • 56

2 Answers2

0

You could create a temporary set containing the members you don't want and then use ZDIFF:

> ZADD mykey 3 uma:7000
(integer) 1
> ZADD mykey 4 umesh:7001
(integer) 1
> ZADD mykey 5 mahes:7002
(integer) 1

Add some temp values:

> ZADD tempkey 0 uma:7000
(integer) 1

And get the difference:

> ZDIFF 2 mykey tempkey WITHSCORES
1) "umesh:7001"
2) "4"
3) "mahes:7002"
4) "5"

Oh. And be sure to clean up the temp set:

> UNLINK tempkey
(integer) 1
Guy Royse
  • 2,739
  • 12
  • 9
0

You can use Lua Script + ZSCAN to do the job. The following is a one-liner that achieves the goal.

redis-cli eval 'local res = redis.call("zscan", KEYS[1], ARGV[1]); local matches = {}; local kv = res[2]; for i=0,(#kv/2-1) do local k = kv[i * 2 + 1]; local v = kv[i * 2 + 2]; if k ~= ARGV[2] then matches[#matches + 1] = k; matches[#matches + 1] = v; end end res[2] = matches; return res' 1 mykey cursor-starting-from-0 uma

There's a similar question for SCAN. I tried to modify the one-liner in that answer, and made a comment. However, the return value for SCAN is quite different from ZSCAN, so I wrote a dedicated answer for it.

for_stack
  • 21,012
  • 4
  • 35
  • 48