REDIS: How to use a Lexicographical Index to save ranges of data

418 Views Asked by At

Background Information

I need to query a value using a key, but the key needs to be evaluated in a specific order of precedence where the order is:

  • if an exact match exists, use the value associated with the matching key
  • if the key falls into a range of keys defined in the db, use the value associated with the range.
  • if there is no matching key, use a default

To better explain the problem, I'll draw a hash like this:

'northam' hash
key       value
=====================
12345     abc
default   ddd
2000[0-10]  bbb

Using the above storage construct, I need to be able:

  • to query using key 12345 and have the db return abc because it found an exact match.
  • If i query using key '33333' then I just want to return the value ddd associated with the "default" key since I don't have a key/value for 33333.
  • If i query using key '2000' or '2004' i want it to find the value bbb.

Question

In REDIS, can I somehow create a key like '2000[0-10]'?
Is there a better way to do this? I know I can programatically expand 2000[0-10] and store each value as a separate entry in the table. But if the user updates this range and changes it to 2000[15-21], then the clean up is going to be a bit messy.

What I've Tried So Far

I've been playing around with sorted sets? I don't fully understand how they work. But so far, I've tried something like this:

127.0.0.1:6379[1]> zadd northam 2000 ddd 2002 ddd
(integer) 1
127.0.0.1:6379[1]>

And now I'm trying to see if I can query for 2000 (or any other value within the range of 2000-2010) and get "ddd" back. but it's not working.

EDIT 1

So after reading a little bit about indexing / secondary indexes, this is the prototype data structure I've been playing with:

127.0.0.1:6379[3]> zadd northamerica 0 2000:2010:1234512345
(integer) 1
127.0.0.1:6379[3]> zadd northamerica 0 2011:2014:00000000000
(integer) 1

The first record, i'm trying to say the starting number in my range is 2000 and the ending number is 2010. For any numbers that fall withing that range, use the value 1234512345 But now I need to know how to execute a query. So for example, if the user requests to know what value to use for key "2009" I don't know how to run the query against this structure to find that it should use 1234512345

EDIT 2

So in the end, I think I've decided to use a lexicographic index, as shown above, and then bake logic into the application itself to interpret. So for example,

127.0.0.1:6379[3]> zrange northamerica 0 -1
1) "2000:2010:12312312345"
2) "2011:2014:00000000000"
3) "2015:2015:11111111111"
127.0.0.1:6379[3]>

The application could query all records for north america and then when it gets the above list back, it could split (into arrays) each record by ":" to determine what ranges exist.

0

There are 0 best solutions below