Sushil Singh
Sushil Singh

Reputation: 116

Search in redis for keys not matching given pattern

The goal is to design a queue with the some values say A. but I have to pick a value from the queue only if incoming value D doesn't matches with B & C.

The relation between A, B and C can be think of as a tabular data.

+------------------+------------------+------------------+
|        A         |        B         |        C         |
+------------------+------------------+------------------+
| 12312            | 123123           | 2323             |
| <some int value> | <some int value> | <some int value> |
+------------------+------------------+------------------+

I have an incoming value D.

Now I have to simply select value A from the row where value of D is not equal to either B or C.

Please note neither of A, B, C are known to in advance. These will be populated by a separate process either in db or redis. The only value I know is D and I have to find the value of A for the first row I find where values B and C are not matching with D.

This is very simple to do if i do this on a relational DB i.e sample query would be

Select A from table where B != D and C != D LIMIT 1

But I am not sure how I can do this using key-value store like redis?

Try 1

The most basic idea will be to maintain a list in redis in following format

somekey: ['a1:b1:c1', 'a2:b2:c2', 'a3:b3:c3', ...]

then I could simply run lrange somekey 0 -1 and then iterate over every elment, split on : untill I find an element where b and c both are not equal to D.

But This approach is very expensive, as I have to iterate over entire every list for every value of D.

Try 2

Another approach I have tried to create redis keys in the following format

+------------------+-----------------------------+
|       Key        |            Value            |
+------------------+-----------------------------+
| prefix_<B1>_<C1> | [<A11>, <A12>, <A13>, ....] |
| prefix_<B2>_<C2> | [<A21>, <A22>, <A23>, ....] |
+------------------+-----------------------------+

The problem with this approach is that redis doesn't support the searching for keys not matching a pattern.

So I have to first get all keys then, do a regex search on application level.

Then once I find a key, i just pop first value from the list at that key.

My preferred approach is to do it using redis, but other solutions are also welcome.

Upvotes: 0

Views: 4099

Answers (1)

MD Ruhul Amin
MD Ruhul Amin

Reputation: 4502

suppose you store values in the following format:

+--------------+-----------------+
| key          | value           |
+--------------+-----------------+
| a1:b1:c1     | any value       |
+--------------+-----------------+
| a2:b2:c2     | any value       |
+--------------+-----------------+
| a3:b3:c3     | any value       |
+--------------+-----------------+
| a4:b4:c4     | any value       |
+--------------+-----------------+

For any value d you want all the keys that does not contain d:d as suffix such as whatever:d:d, here is the following regex that will return all the keys that does not d:d in suffix.

KEYS *[^d:d]

suppose values of d is 123 then the pattern will be: *[^123:123].

Here are some cases which I've tested in my console:

127.0.0.1:6379> set 123:456:789 one
OK
127.0.0.1:6379> set 123:456:780 two
OK
127.0.0.1:6379> set 123:456:787 two
OK
127.0.0.1:6379> set 123:455:787 two
OK
127.0.0.1:6379> set aaa:bbb:ccc abc
OK
127.0.0.1:6379> set aaa:ddd:ddd abc
OK
127.0.0.1:6379> keys *
1) "123:456:789"
2) "123:456:787"
3) "123:455:787"
4) "aaa:ddd:ddd"
5) "aaa:bbb:ccc"
6) "123:456:780"
127.0.0.1:6379> keys aaa:*[^ddd:ddd]
1) "aaa:bbb:ccc"
127.0.0.1:6379> keys *[^ddd:ddd]
1) "123:456:789"
2) "123:456:787"
3) "123:455:787"
4) "aaa:bbb:ccc"
5) "123:456:780"

see command keys *[^ddd:ddd] returning all the keys which does not matched with our expected key.

1) "123:456:789"
2) "123:456:787"
3) "123:455:787"
4) "aaa:bbb:ccc"
5) "123:456:780"

for more check this link: REDIS KEYS

You can also use REDIS SCAN command to fetch not matching keys:

scan 0 MATCH *[^d:d] count 1000

Upvotes: 2

Related Questions