Search code examples
redisglob

Redis find pattern keys that match string


I know that Redis has MATCH as a part of SCAN (as detailed here) to find keys that match a glob style pattern (i.e. sub.domain.com could be returned from scan 0 MATCH *.domain.com)

My question is if there is a way to perform the reverse operation. If my keys are glob style patterns (i.e. *.domain.com is one of the keys) how can I search to see what keys have patterns that match sub.domain.com?

One thought was to use EVAL to write a Lua script to do this, but I would think that would be fairly resource intensive? Is there some other way to approach this?


To make things a little clearer, here are some example keys (seperated by commas) (I'm not going to worry about the values for now as they don't really apply to this question), queries and the responses that I would expect the queries to generate:

Keys: *img.myserver.com*, *.mywebsite.com*, *www.example.com/images*

Queries -> expected responses (matched keys)

scan 0 REV-MATCH https://img.myserver.com/myimg.jpg -> *img.myserver.com*

scan 0 REV-MATCH http://www.myserver.com/otherimg.jpg -> No matches

scan 0 REV-MATCH http://www.mywebsite.com/blah/blah.jpg -> *.mywebsite.com*

scan 0 REV-MATCH https://www.example.com/images/old/a.jpg -> *www.example.com/images*

REV-MATCH (Reverse Match) is a function that doesn't exist - but I'm hoping that similar functionality can be found some other way. It is possible for there to be multiple matches if two keys had glob patterns that could match the same string in some scenarios (in my use case, however, this wouldn't happen as I would always ensure the glob patterns never overlapped)


Solution

  • Unless I'm wrong, I think that you're overthinking it. A GET *.domain.com (i.e. replace "sub" with "*") should do it. If unfound, continue with a GET *.com, and so forth until ending with GET *, which should be the "root" of all things.


    Updated answer

    Ok, I see. So, no, SCAN isn't the way but I know of at least two other paths you can try. Give me a shout or open a new question if you run into any dead ends ;)

    The Path of Sorted Sets and Lexicographical Ranges

    Go to https://redis.io/topics/indexes#lexicographical-indexes and read (may take more than one iteration, and I recommend reading the entire thing actually). Then, given your requirements, remember that you can do suffix matching by storing (and searching) the reverse in another Sorted Set.

    The RediSearch Path

    Take a look at http://redisearch.io, a Redis module that implements a full search engine (autocomplete included(tm)).

    Disclaimer: I work at Redis Labs, home of the open source Redis and provider of commercial solutions that leverage on it, including the above mentioned module (open source, AGPL licensed).