6
votes

By using phpredis, I have saved some data in pagination like this:

   review/itemA/1
   review/itemA/2 

where 1 and 2 are page numbers. I read in the document that you can use wildcards to retrieve multiple keys.

$allKeys = $redis->keys('*');   // all keys will match this.
$keyWithUserPrefix = $redis->keys('user*');

But can I delete all the old keys using wildcards as well when someone has posted a new review? Can I do something like:

$redis->delete('review/itemA/*'); // or  $redis->delete('review/itemA*')

It didn't work however.

7
Never use keys command on production environment as it will block the whole DB until the searched key is found. Instead you can use Scan to search specific key for production env. - Akash Gangrade

7 Answers

4
votes

No - Redis' DELlete does not accept wildcards, you have to name the keys explicitly. See here for possible directions: https://stackoverflow.com/a/23399125/3160475

2
votes

When using phpredis, you can get the prefix (which phpredis automatically prepends everywhere) and delete a pattern of keys that way :

<?php
...

$prefix = $redisClient->getOption(Redis::OPT_PREFIX);
$redisClient->delete(array_map(
    function ($key) use ($prefix) {
        return str_replace($prefix, '', $key);
    }, $redisClient->keys('*'))
);
1
votes
$bash = 'redis-cli --scan --pattern "' . $path . '*" | xargs -L 1000 redis-cli DEL';

$res = @shell_exec($bash);
1
votes

I just use

$redis->delete($redis->keys('*'));

It's works fine for me.

1
votes

Predis (->del) allows to pass a keys array too.
It works here and is faster than the del inside the foreach.

$prefix = $this->client->getOptions($this->OPT_PREFIX);
$keys = $this->client->keys("$key*");
if ($keys) $this->client->del($keys);
0
votes

With Predis, I do it like this:

    public function delete($key) {
        $keys = $this->client->keys($key);
        foreach ($keys as $key) {
            $this->client->del($key);
        }
    }
0
votes

There is no wildcard for delete function. workaround as follows,

// returns total number of keys deleted
function delete($key) {
    if (empty($key)) {  // empty key can delete all
      return false;
    }
    $keys = $redis->keys("$key*");  // keys() function returns array of key strings. `*` wild card pattern can be changed as per need
    if(!$keys) {
        return 0;
    }
    $prefix = $redis->getOption(\Redis::OPT_PREFIX); // keys already have prefix, so we clear until delete finish.
    $redis->setOption(\Redis::OPT_PREFIX, '');
    $count = $redis->del($keys);  // del() function delete array of keys and returns number of keys deleted.
    $redis->setOption(\Redis::OPT_PREFIX, $prefix);

    return $count;
}

Note: As @Akash Gangrade commented, keys() not advised to use due to performance. you can consider Tags based cache invalidation like https://symfony.com/doc/current/components/cache/cache_invalidation.html#tag-aware-adapters