Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding values by using partial key name in a Redis Sorted Set

Tags:

redis

I have a sorted set which has the following key name and values :

zrange bargraph:branch:1:category:2:product:4
1) "76"
2) "55"
3) "10"
4) "84"

Is there a mechanism in redis where I can use a wildcard character(maybe an ?) when using zrange to still get the same values? In other words, does redis support zrange bargraph:branch:1:category:2? If not, how best can I get all the values if I only know the category id(2) and not the product id(4) without using a different sorted set?

like image 510
sniper Avatar asked Dec 02 '22 19:12

sniper


2 Answers

Here is an updated answer for 2015.

If you can upgrade Redis above 2.8, the SCAN command with MATCH will work for this. Before that version, not so much, and do NOT use the KEYS command except in a development environment.

http://redis.io/commands/scan

Example on command line:

$ redis-cli
127.0.0.1:6379> scan 0 match V3.0:*
1) "0"
2) 1) "V3.0:UNITTEST55660BC7E0C5B"
   2) "V3.0:shop.domain.com:route"
   3) "V3.0:UNITTEST55660BC4A2548"
127.0.0.1:6379> scan 0 match V1.0:*
1) "0"
2) (empty list or set)
127.0.0.1:6379> scan 0 match V3.0:*
1) "0"
2) 1) "V3.0:UNITTEST55660BC7E0C5B"
   2) "V3.0:shop.domain.com:route"
   3) "V3.0:UNITTEST55660BC4A2548"

Example in PHP:

// Initialize our iterator to NULL
$iterate = null;

// retry when we get no keys back
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);

while ($arr_keys = $redis->scan($iterate, 'match:*')) {
    foreach ($arr_keys as $str_key) {
        echo "Here is a key: $str_key\n";
    }
    echo "No more keys to scan!\n";
}

Note, php code is not tested and from the core documentation for example here. Production code would need to be modified depending on the keys needed to look up.

For those on Ubuntu here are the instructions to upgrade php5-redis:

  1. Download the 2.2.7 package here: http://pecl.php.net/package/redis
  2. $ php -i | grep Redis Redis Support => enabled Redis Version => 2.2.4
  3. Follow instructions in README to phpize, configure, make install
  4. Create a symlink for command line cli package: cd /etc/php5/cli/conf.d && sudo ln -s ../../mods-available/redis.ini 20-redis.ini
  5. $ php -i | grep Redis Redis Support => enabled Redis Version => 2.2.7
like image 153
Ligemer Avatar answered Mar 15 '23 05:03

Ligemer


As you've mentioned, KEYS is inefficient because the engine performs a linear scan for keys. Unfortunately, there is no wildcard solution such as you are looking for

Consider using a SET for your product keys per category:

SADD bargraph:branch:1:category:2 1 2 3 4

to fetch all set category members do:

SMEMBERS bargraph:branch:1:category:2

If you don't care about summing your scores, or have different items per a sorted set, you can do a union of your per product sorted sets like this:

ZUNIONSTORE bargraph:branch:1:category:2:product:all 4 bargraph:branch:1:category:2:product1 bargraph:branch:1:category:2:product2 bargraph:branch:1:category:2:product3 bargraph:branch:1:category:2:product4

and now you can zrange bargraph:branch:1:category:2:product:all

You pipeline the above operations for better performance

like image 41
Ori Dar Avatar answered Mar 15 '23 05:03

Ori Dar