Full text search in Redis using RediSearch
Being quite a popular solution as a database platform, Redis now has powerful extension that implements full text search. The solution is good enough to fit most use cases, including support of different languages, attributes filtering, fuzzy search, prefix search, aggregations, sharding and many more. Oh, and search indexing is real time. Let’s see it in practice.
Installing RediSearch
This is a part of Redis Stack, so the best option is to install it as a whole platform. Still, you can only download and add separate RediSearch module to your redis.conf
:
loadmodule /path/to/redisearch.so
After restarting Redis server, we can use FT.*
methods which manage full text search functionality.
How everything works
In order to get use of full text search feature, we have to store documents in hashes, initialize index with FT.CREATE
command and the use FT.SEARCH
to search by text:
Let’s insert couple of text docs:
redis-cli 'hset post:1 title "hello world" body "this is a cool document"'
redis-cli 'hset post:2 title "goodbye everybody" body "this is the best document"'
This will create two hashes, named post:1
and post:2
with title
and body
text fields.
Creating indexes
Now we have to create index, so these (and new future) documents get indexed and prepared for full text search:
FT.CREATE post_index prefix 1 post: SCHEMA title TEXT body text
Here we have created post_index
index that will index all Redis hashes keys starting with post:
prefix. Only title
and body
fileds will be indexed. Index is instantly ready to search.
Searching index
Searching is as easy as calling FT.SEARCH
command with index name and phrase to search:
FT.SEARCH post_index "world"
Real time indexing
When new documents arrive, they are being indexed automatically:
redis-cli 'hset post:3 title "really?" body "yeah"'
This new document will become available for search in our index immediately:
> ft.search post_index "really"
1) (integer) 1
2) "post:3"
3) 1) "title"
2) "really?"
3) "body"
4) "yeah"
Searching on specific fields
We can choose which fields to search on. To search on title
field only:
ft.search post_index "@title:world"
Searching by any word from a list
Logical “OR” can be used to find documents based on any word from a given list. To find all documents matching either hello
or goodbye
:
ft.search post_index "hello|goodbye"
Paging results
To get paged results we can use SQL-style LIMIT
param. To return found documents from 11th
to 15th
:
ft.search post_index "world" LIMIT 10, 5
Excluding searches
Using —
symbol at the beginning of a phrase will exclude found documents from results instead of returning them:
ft.search post_index "-foo"
Partial search
We can also search only on a part of a word using *
. To find all documents with a word starting with good...
:
ft.search post_index "good*"
This is limited to prefixes only (can’t search something like *bye
).
Fuzzy matching
One of the coolest features is fuzzy search which allows aproximate searches. This is good in cases when input query or documents can contain errors. In order to fuzzy match, we need to wrap our phrase with %
:
ft.search post_index "%wold%"
This will match document with world
word although query has wold
in it (without r
). See query syntax docs for more cases.
Summary
RediSearch is a powerfull and feature rich full text search engine on top of popular NoSQL database. Given proven Redis scalability and performance from one side and features from other side, it can be efficient production solution for full text search in your app. And no need to plugin any third party solutions like Manticore.