Reputation: 165
I'm using Redis cache on Laravel 5.2, and I have my keys with 2 tags (basically), the year and the source.
Example:
$this->cache->tags(['online', 2016])->put("key1", $value1, 10));
$this->cache->tags(['online', 2016])->put("key2", $value2, 10));
$this->cache->tags(['online', 2017])->put("key3", $value3, 10));
$this->cache->tags(['online', 2017])->put("key4", $value4, 10));
$this->cache->tags(['database', 2016])->put("key5", $value5, 10));
$this->cache->tags(['database', 2016])->put("key6", $value6, 10));
$this->cache->tags(['database', 2017])->put("key7", $value7, 10));
$this->cache->tags(['database', 2017])->put("key8", $value8, 10));
I want to flush the cache for the tags 2016 & online.
Using this $this->cache->tags(['online', 2016])->flush();
It will flush everything with any of the tags, i.e., either online
or 2016
(in this case key1, key2, key3, key4, key5, key6).
I want to delete everything including all the tags, i.e., both online
and 2016
(in this case only key1 and key2)
Upvotes: 6
Views: 3983
Reputation: 2308
I think I would make a key to fit the delete ...
$this->cache->tags([andKey('online', 2016)])->put("key1", $value1, 10));
$this->cache->tags([andKey('online', 2016)])->put("key2", $value2, 10));
$this->cache->tags([andKey('online', 2016)])->flush();
helper:
function andKey($a, $b)
{
return sprintf("%s.%s", $a, $b);
}
Bit more work, but will save loads of headache when cache system is changed.
edit: As suggested in comments you can add all keys and flush on any 3.
$this->cache->tags(['online', '2016', andKey('online', 2016)])->put("key1", $value1, 10));
$this->cache->tags(['online', '2016', andKey('online', 2016)])->put("key2", $value2, 10));
$this->cache->tags([andKey('online', 2016)])->flush();
helper:
function andKey($a, $b)
{
return sprintf("combined.%s.%s", $a, $b);
}
Upvotes: 2
Reputation: 323
In 'yourKeyGoesHere' you can insert a string used as same as a like with a * or insert directly the exactly key.
//Get all cached data ...
$redis = Cache::getRedis();
$a_keys = $redis->keys("*yourKeyGoesHere*");
foreach ($a_keys as $key){
//Your Action on key ... (Example delete / forget)
$redis->del($key);
}
Upvotes: 0
Reputation: 40653
So this took a bit of digging but here's the verdict.
Yes this is technically possible (the best kind of possible?)
First of all, the RedisTaggedCache
(responsible for implementing tagging in redis) stores all tag member keys in a redis set. Here's how to discover where it is and how you can get all keys:
function getAllTagKeys($cache,$tags) {
$tagStore = new TagSet($cache->getStore(),$tags);
$key = "<prefix>:{$tagStore->getNamespace()}:". RedisTaggedCache::REFERENCE_KEY_STANDARD;//use REFERENCE_KEY_FOREVER if the keys are cached forever or both one after the other to get all of them
return collect($cache->getRedis()->smembers($key));
}
Then you can do:
getAllTagKeys($this->cache, ["online"])
->insersect(getAllTagKeys($this->cache, ["2016"]))
->each(function ($v) {
$this->cache->getRedis()->del();
});
This looks like a horrible way to do this. Perhaps it's more sensible to make a feature request to Laravel since this looks like it's something they should be exposing?
Upvotes: 3