31

I'm building a REST API with Lumen and want to cache some of the routes with Redis. E.g. for the route /users/123/items I use:

$items = Cache::remember('users:123:items', 60, function () {
  // Get data from database and return
});

When a change is made to the user's items, I clear the cache with:

Cache::forget('users:123:items');

So far so good. However, I also need to clear the cache I've implemented for the routes /users/123 and /users/123/categories since those include an item list as well. This means I also have to run:

Cache::forget('users:123');
Cache::forget('users:123:categories');

In the future, there might be even more caches to clear, which is is why I'm looking for a pattern/wildcard feature such as:

Cache::forget('users:123*');

Is there any way to accommodate this behavior in Lumen/Laravel?

j3491
  • 475
  • 1
  • 5
  • 11

2 Answers2

32

You can use cache tags.

Cache tags allow you to tag related items in the cache and then flush all cached values that have been assigned a given tag. You may access a tagged cache by passing in an ordered array of tag names. For example, let's access a tagged cache and put value in the cache:

Cache::tags(['people', 'artists'])->put('John', $john, $minutes);

You may flush all items that are assigned a tag or list of tags. For example, this statement would remove all caches tagged with either people, authors, or both. So, both Anne and John would be removed from the cache:

Cache::tags(['people', 'authors'])->flush();
Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279
  • 1
    Thanks, I actually read about tags but didn't realize I could use it for dynamic tags with user ids. So I guess something like: `Cache::tags(['user:123'])->remember('items', 60, function () {...`? – j3491 Mar 27 '17 at 14:12
  • 47
    Not supported when using 'file' or 'database' driver :( – mattyh88 Oct 30 '17 at 10:44
  • 3
    tags are a pain in the ass in every key value store. no matter what driver you use. a requested wildcard solution can be faster in most systems. – iRaS Nov 15 '19 at 10:56
  • 3
    This isn't supported with DynamoDB on Vapor, either. – Elliot May 14 '20 at 13:32
1

First Get the cached keys with pattern

$output = Redis::connection('cache')->keys("*mn");
Output
[
   "projectName_database_ProjectName_cahe_:mn"
]

Output contain from four parts

  • redis prefix ==> config('database.redis.options.prefix')
  • cache prefix ==> config('cache.prefix')
  • seperator ":"
  • your cahced key "mn"

Get Key

$key = end(explode(":", $output[0]));
Cache::forget($key); // delete key
Ahmed Eid
  • 192
  • 1
  • 8