I am a Sr. Software Developer at Oracle Cloud. The opinions expressed here are my own and not necessarily those of my employer.
RediSearch Module
In previous post I wrote about different ways we can search for records in Redis. In this article I want to do a deeper dive on RediSearch module.
Basic search
We will use Redis as the primary DB leveraging Ohm library. But now we want to build more sophisticated indexes with RediSearch, use NUMERIC
filter and other advanced options. And we will continue using RediSearchRails library.
Generate random seed data:
When we look in Redis we see various keys for RediSearch. There are Hashes which contain key / value pairs for name, email, status, age and height. RediSearchRails uses GlobalID to create unique key.
Separately we have custom data types for indexes:
Now we can run User.ft_search(keyword: 'active')
or in redis-cli do FT.SEARCH User active
. Similar searches can be done by name or email. We could search for all users with gmail
address because RediSearch will index gmail
as keyword.
RediSearchRails library also provides additional ft_add_all
, ft_del_all
, ft_search_format
and ft_search_count
methods (not present in RediSearch module). ft_search_format
will return data as an array of hashes which is common pattern in ORMs like ActiveRecord or Mongoid.
Advanced options
Numeric filter
numeric
indexes allow us to filter search results if we want users of a certain age or height range.
Indexing data already in Redis
In our case we are using Redis both as primary DB and for RediSearch indexes. The core attributes (name, email, …) are stored as Hashes in Ohm records and then created separately by RediSearch. We can use FT.ADDHASH
to index existing hashes and avoid creating duplicates.
Pagination
What if we have thousands of records that match our search criteria? We do not want to return all results at once. RediSearch supports LIMIT offset num
(default offset is 0 and num is 10). We can easily get the total number of results and request them in batches.
Auto complete
RediSearch module also has FT.SUGADD
, FT.SUGGET
, FT.SUGDEL
and FT.SUGLEN
methods. Using these commands we can build an autocomplete indexes to search for users by specific attributes. These Redis keys are completely separate from the other indexes. RediSearchRails library creates a Redis key by combining model name with attribute (User:name
).
In addition to methods supported by RediSearch module RediSearchRails library adds ft_sugadd_all
and ft_sugdel_all
. They accept attribute name (User.ft_sugadd_all(attribute: 'name')
) and will loop through all records adding/deleting strings to auto-complete dictionaries for that attribute. This can be useful when we have a table with specific records and we want to build auto-complete search on specific attribute.
Conclusion
There are many other advanced options in RediSearch module. For example, we can use GEO filters, stem keywords and do much more advanced querying. I am working on adding support for these to RediSearchRails library. I also want to add extra features to my library such as custom sopwords configuration and ability to specify minimum keyword length to index.