RediSearch is a powerful text search and secondary indexing engine, built on top of Redis as a Redis module.

Unlike Redis search libraries, it does not use Redis’ internal data structures. Using its own highly optimized data structures and algorithms, RediSearch allows for advanced search features, with high performance and a small memory footprint. It can perform simple text searches as well as complex structured queries, filtering by numeric properties and geographical distances

To learn about how to use RediSearch read:

1 Build readiserch

The following compile template was run on CentOS 8.

1.1 Pre-requisites

Install this libraries as user root:

dnf install gcc-c++

1.2 Download

From redis directory download RediSearch code from git.

su - redis
cd /home/redis
git clone    
cd RediSearch
ls -l
drwxrwxr-x  2 redis redis   140 Apr 24 00:31 cmake
-rw-rw-r--  1 redis redis  6575 Apr 24 00:31 CMakeLists.txt
-rw-rw-r--  1 redis redis   331 Apr 24 00:31 codecov.yml
drwxrwxr-x  4 redis redis    39 Apr 24 00:31 deps
drwxrwxr-x  3 redis redis    37 Apr 24 00:31 docker
drwxrwxr-x  4 redis redis  4096 Apr 24 00:31 docs
-rwxrwxr-x  1 redis redis   727 Apr 24 00:31 getver
-rw-rw-r--  1 redis redis  5793 Apr 24 00:31 LICENSE
-rw-rw-r--  1 redis redis  7784 Apr 24 00:31 Makefile
-rw-rw-r--  1 redis redis  2165 Apr 24 00:31 mkdocs.yml
-rwxrwxr-x  1 redis redis  6908 Apr 24 00:31
-rw-rw-r--  1 redis redis   557 Apr 24 00:31 ramp.yml
-rw-rw-r--  1 redis redis 12555 Apr 24 00:31
drwxrwxr-x 10 redis redis  4096 Apr 24 00:31 src
drwxrwxr-x  2 redis redis   131 Apr 24 00:31 srcutil
-rwxrwxr-x  1 redis redis  2170 Apr 24 00:31
drwxrwxr-x  8 redis redis    93 Apr 24 00:31 tests

1.3 Compile

From RediSearch create a build directory and from it, run cmake.

mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo

When running the command cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo if the gcc-c++ is not installed you will get the following error:

CMake Error at CMakeLists.txt:6 (project):
No CMAKE_CXX_COMPILER could be found.

Tell CMake where to find the compiler by setting either the environment
variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
to the compiler, or to the compiler name if it is in the PATH.

Error: --system-information failed on internal CMake!

To solve the problem you can run the follwoing command:

yum install gcc-c++

Go back to RediSearch directory and from it, run make.

Run this commands with root privileges or user root:

cd ..
Scanning dependencies of target rscore
[  0%] Building C object CMakeFiles/rscore.dir/src/alias.c.o
[  1%] Building C object CMakeFiles/rscore.dir/src/buffer.c.o
[  1%] Building C object CMakeFiles/rscore.dir/src/byte_offsets.c.o
[  2%] Building C object CMakeFiles/rscore.dir/src/cndict_loader.c.o

[ 99%] Building C object src/rmutil/CMakeFiles/test_vector.dir/test_vector.c.o
[100%] Linking C executable test_vector
[100%] Built target test_vector

When building RediSearch, the following error may appear:

Makefile:3: deps/readies/mk/main: No such file or directory
Makefile:105: /defs: No such file or directory
Makefile:109: /rules: No such file or directory
./ line 54: /home/redis/RediSearch/deps/readies/shibumi/functions: No such file or directory
./ line 54: /home/redis/RediSearch/deps/readies/shibumi/functions: No such file or directory
make: *** No rule to make target `/rules'.  Stop.

This is because there are files that haven't been cloned correctly with the git clone command.

In order to fix this, run the following commands:

cd /home/redis/RediSearch/deps/
rm -rf readies/
git clone

Now the readies folder should have the following files:

ls readies/
bin  cetara  docs  LICENSE  mk  paella  shibumi  wd40
After the compilation is complete, you can see the file in build directory.

1.4 Start Redis with ReadiSeach

Copy to /home/redis/bin/

If the folder home/redis/bin does not exist, create it.
mkdir -p /home/redis/bin/
mv build/ /home/redis/bin/
redis-server --loadmodule /home/redis/bin/
50239:C 01 Dec 2019 20:52:27.598 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
50239:C 01 Dec 2019 20:52:27.598 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=50239, just started
50239:C 01 Dec 2019 20:52:27.598 # Configuration loaded
50239:M 01 Dec 2019 20:52:27.599 * Increased maximum number of open files to 10032 (it was originally set to 256).
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 5.0.7 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 50239
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |         
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           

50239:M 01 Dec 2019 20:52:27.600 # Server initialized
50239:M 01 Dec 2019 20:52:27.951 * <ft> RediSearch version 99.99.99 (Git=v1.6.0-373-gac16a4d8)
50239:M 01 Dec 2019 20:52:27.951 * <ft> Low level api version 1 initialized successfully
50239:M 01 Dec 2019 20:52:27.951 * <ft> concurrent writes: OFF, gc: ON, prefix min length: 2, prefix max expansions: 200, query timeout (ms): 500, timeout policy: return, cursor read size: 1000, cursor max idle (ms): 300000, max doctable size: 1000000, search pool size: 20, index pool size: 8, 
50239:M 01 Dec 2019 20:52:27.951 * <ft> Initialized thread pool!
50239:M 01 Dec 2019 20:52:27.951 * Module 'ft' loaded from redis/
50239:M 01 Dec 2019 20:52:27.951 * Ready to accept connections

2 Continue installation

Once you launch the previous configuration and it connects, you have to close the shell where you launched it and open a new one, to continue with the Redis installation process on the previous page: HERE  

3 Indexes

RediSearch is a Redis module that provides querying, secondary indexing, and full-text search for Redis. To use RediSearch, you first declare indexes on your Redis data. You can then use the RediSearch query language to query that data. RediSearch uses compressed, inverted indexes for fast indexing with a low memory footprint. RediSearch indexes enhance Redis by providing exact-phrase matching, fuzzy search, and numeric filtering, among many other features.

3.1 Creating an index

Creates an index with the given spec. The index name will be used in all the key names so keep it short!

FT.CREATE {index} 
    [STOPWORDS {num} {stopword} ...]
    SCHEMA {field} [TEXT [NOSTEM] [WEIGHT {weight}] [PHONETIC {matcher}] | NUMERIC | GEO | TAG [SEPARATOR {sep}] ] [SORTABLE][NOINDEX] ...                

Creating an index with fields and weights (default weight is 1.0)

FT.CREATE products SCHEMA title TEXT price NUMERIC

3.2 Add documents

To add documents to and index

FT.ADD {index} {docId} {score} 
  [LANGUAGE {language}] 
  [PAYLOAD {payload}]
  [IF {condition}]
  FIELDS {field} {value} [{field} {value}...]
FT.ADD products prod1 	1.0 FIELDS title "Apple AirPods Pro" price 250
FT.ADD products prod2 	1.0 FIELDS title "Acer Aspire 5" price 445
FT.ADD products prod3 	1.0 FIELDS title "Bose SoundLink Color II" price 129
FT.ADD products prod4 	1.0 FIELDS title "DJI Mini 2 – Ultralight and Foldable" price 449
FT.ADD products prod5 	1.0 FIELDS title "Toshiba 32 LCD TV" price 250
FT.ADD products prod6 	1.0 FIELDS title "Fujifilm Instax Mini 11" price 99
FT.ADD products prod7 	1.0 FIELDS title "Rolex Cosmograph Daytona Ice Blue" price 75700
FT.ADD products prod8 	1.0 FIELDS title "GoPro HERO8 Black 4K Waterproof Action Camera" price 259.99
FT.ADD products prod9 	1.0 FIELDS title "Samsung 42 LCD TV" price 350
FT.ADD products prod10 	1.0 FIELDS title "Panasonic LUMIX FZ80 4K Digital Camera" price 297.99
FT.ADD products prod11 	1.0 FIELDS title "LG Electronics 32-Inch 720p LED TV" price 520

3.3 Search

To perform a search on an index

  [FILTER {numeric_field} {min} {max}] ...
  [GEOFILTER {geo_field} {lon} {lat} {raius} m|km|mi|ft]
  [INKEYS {num} {key} ... ]
  [INFIELDS {num} {field} ... ]
  [RETURN {num} {field} ... ]
  [SUMMARIZE [FIELDS {num} {field} ... ] [FRAGS {num}] [LEN {fragsize}] [SEPARATOR {separator}]]
  [HIGHLIGHT [FIELDS {num} {field} ... ] [TAGS {open} {close}]]
  [SLOP {slop}] [INORDER]
  [LANGUAGE {language}]
  [EXPANDER {expander}]
  [SCORER {scorer}]
  [PAYLOAD {payload}]
  [SORTBY {field} [ASC|DESC]]
  [LIMIT offset num]    

Search example 1

FT.SEARCH products "lcd tv"
1) (integer) 2
2) "prod2"
3) 1) "title"
   2) "Samsung 42 LCD TV"
   3) "price"
   4) "350"
4) "prod1"
5) 1) "title"
   2) "Toshiba 32 LCD TV"
   3) "price"
   4) "250"

Search example 2

FT.SEARCH products "lcd tv" FILTER price 300 400
1) (integer) 1
2) "prod2"
3) 1) "title"
   2) "Samsung 42 LCD TV"
   3) "price"
   4) "350"

3.4 Sorting by indexed fields

As of RediSearch 0.15, it is possible to bypass the scoring function mechanism, and order search results by the value of different document properties (fields) directly - even if the sorting field is not used by the query. For example, you can search for first name and sort by last name.


This section is incomplete and will be concluded as soon as possible.

3.5 Dropping the index

FT.DROP products

3.6 Minimum query characters (MINPREFIX)

We can change the minimum number of characters we allow for prefix queries (e.g. bla* ). Setting it to 1 can hurt performance (default value is 2). It must be done before the creation of the index.


3.7 Maximum number of expansions (MAXEXPANSIONS)

We can change the maximum number of expansions we allow for query prefixes. Setting it too high can cause performance issues (default value is 200). If MAXEXPANSIONS is reached, the query will continue with the first acquired results and will not search anymore.


Let's explain how this works and how it affects to the search:


Imagine we set the MAXEXPANSIONS to 2, MINPREFIX to 1 and our index looks like the following:

        index        name
        0001         Red parrot
        0002         Orange parrot
        0003         White paper
        0004         Blue pen
        0005         Green pickle

If we do the following query:

FT.SEARCH myIndex "@name: Green p*"

The output returns no result. That's because the redisearch indexes all the words he find starting by p, up to MAXEXPANSIONS.

In our case, MAXEXPANSIONS = 2, so the words starting by p in alphabetical order:

        parrot   --> position 2 Still in MAXEXPANSIONS range --> (Red parrot     considered in query)
                                                             --> (Orange parrot  considered in query)
        paper    --> position 1 Still in MAXEXPANSIONS range --> (White paper    considered in query)
        ------------------------------------------------------------------------------------------------------ Here MAXEXPANSIONS is full
        pen      --> position 3 Not in MAXEXPANSIONS range   --> (Blue pen       NOT considered in query)
        pickle   --> position 4 Not in MAXEXPANSIONS range   --> (Green pickle   NOT considered in query)

And because neither White paper, Red parrot nor Orange parrot satisfy the Green p* query, therefore no result is returned.

4 Auto-complete suggestions

The auto-suggest is independent from the search index and needs to be built independently, as you can see.

        FT.SUGADD {key} {string} {score} [INCR] [PAYLOAD {payload}]

You have three options:

  • Suggestions can have payloads, which can be any string you want, or even whole documents as JSON (they are not searchable though). So just put whatever payload you want for a suggestion.
  • The index itself supports prefix searches disconnected from the auto-complete. You can use a prefix query (FT.SEARCH idx "foo*") to search documents containing a prefix.
  • Best method: take the top completion suggesion and run that as a search query.

FT.SUGADD autocomplete "hello world" 100
FT.SUGGET autocomplete "he"
1) "hello world"

4.1 Suggestions length

You can query the length of a suggestion index (key).

FT.SUGLEN autocomplete
(integer) 1

4.2 Drop suggestions

To drop a suggestions you should use the DEL command. The command will return the length of the suggesions deleted. If suggestion index does not exits, it will return 0.

DEL autocomplete
(integer) 1

5 Aggregations

Aggregations are a way to process the results of a search query, group, sort, transform them and extract analytic insights from them.

5.1 Core concepts

The basic idea of an aggregate query is this:

  • Perform a search query, filtering for records you wish to process.
  • Build a pipeline of operations that transform the results by zero or more steps of:
    • Group and Reduce: grouping by fields in the results, and applying reducer functions on each group.
    • Sort: sort the results based on one or more fields.
    • Apply Transformations: Apply mathematical and string functions on fields in the pipeline, optionally creating new fields or replacing existing ones.
    • Limit: Limit the result, regardless of sorting the result.
    • Filter: Filter the results (post-query) based on predicates relating to its values.

The pipeline is dynamic and reentrant, and every operation can be repeated. For example, you can group by property X, sort the top 100 results by group size, then group by property Y and sort the results by some other property, then apply a transformation on the output.

5.2 Aggregate request format

The aggregate request's syntax is defined as follows:

      [LOAD {nargs:integer} {property:string} ...]
        {nargs:integer} {property:string} ...
          {nargs:integer} {arg:string} ...
          [AS {name:string}]
      ] ...
        {nargs:integer} {string} ...
        [MAX {num:integer}] ...
      ] ...
        AS {name:string}
      ] ...
      [FILTER {EXPR:string}] ...
      [LIMIT {offset:integer} {num:integer} ] ...

5.3 Examples

Let's create first the index we will be working on and let's fill it with some documents. Afterwards we shall see some examples.


Create an index


Add documents to the index

FT.ADD ptest I00001 1.0 FIELDS name "Boli BIC black"            price 0.8 color "BLACK"          brand "BIC"
FT.ADD ptest I00002 1.0 FIELDS name "Boli BIC blue"             price 0.8 color "BLUE"           brand "BIC"
FT.ADD ptest I00003 1.0 FIELDS name "Boli BIC red"              price 0.8 color "RED"            brand "BIC"
FT.ADD ptest I00004 1.0 FIELDS name "Boli BIC multicolor"       price 3.8 color "BLACK,RED,BLUE" brand "BIC"
FT.ADD ptest I00005 1.0 FIELDS name "Boli Standler punta fina"  price 2.8 color "BLUE"           brand "STANDLER"
FT.ADD ptest I00006 1.0 FIELDS name "Boli Standler punta fina"  price 2.8 color "RED"            brand "STANDLER"
FT.ADD ptest I00007 1.0 FIELDS name "Boli Standler punta fina"  price 2.8 color "GREEN"          brand "STANDLER"
FT.ADD ptest I00008 1.0 FIELDS name "Pilot Gold"                price 5.8 color "GOLD"           brand "PILOT"
FT.ADD ptest I00009 1.0 FIELDS name "Pilot Silver"              price 4.8 color "SILVER"         brand "PILOT"

Return the maximum price of all documents

FT.AGGREGATE ptest * GROUPBY 0 REDUCE MAX 1 @price AS max_price
1) (integer) 1
2) 1) "max_price"
   2) "5.8"

Return the minimum price of all documents

FT.AGGREGATE ptest * GROUPBY 0 REDUCE MIN 1 @price AS min_price
1) (integer) 1
2) 1) "min_price"
   2) "0.8"

Return the total count of all documents

1) (integer) 1
2) 1) "total_count"
   2) "9"

Return all distinct brands

FT.AGGREGATE ptest * GROUPBY 1 @brand
1) (integer) 3
2) 1) "brand"
   2) "STANDLER"
3) 1) "brand"
   2) "BIC"
4) 1) "brand"
   2) "PILOT"

Return all distinct colors (considering every color within color property as a single color)

FT.AGGREGATE ptest * GROUPBY 1 @color APPlY split(@color) AS dist_color GROUPBY 1 @dist_color
1) (integer) 6
2) 1) "dist_color"
   2) "BLUE"
3) 1) "dist_color"
   2) "RED"
4) 1) "dist_color"
   2) "SILVER"
5) 1) "dist_color"
   2) "GREEN"
6) 1) "dist_color"
   2) "BLACK"
7) 1) "dist_color"
   2) "GOLD"

Return the result of the query sorted by name

FT.AGGREGATE ptest * SORTBY 1 @name
1) (integer) 9
 2) 1) "name"
    2) "boli bic black"
 3) 1) "name"
    2) "boli bic blue"
 4) 1) "name"
    2) "boli bic multicolor"
 5) 1) "name"
    2) "boli bic red"
 6) 1) "name"
    2) "boli standler punta fina"
 7) 1) "name"
    2) "boli standler punta fina"
 8) 1) "name"
    2) "boli standler punta fina"
 9) 1) "name"
    2) "pilot gold"
10) 1) "name"
    2) "pilot silver"

5.4 Supported GROUPBY reducers

Reducer Format Description
COUNT REDUCE COUNT 0 Count the number of records in each group.
COUNT_DISTINCT REDUCE COUNT_DISTINCT 1 {property} Count the number of distinct values for property.
COUNT_DISTINCTISH REDUCE COUNT_DISTINCTISH 1 {property} Same as COUNT_DISTINCT - but provide an approximation instead of an exact count, at the expense of less memory and CPU in big groups.
SUM REDUCE SUM 1 {property} Return the sum of all numeric values of a given property in a group. Non numeric values if the group are counted as 0.
MIN REDUCE MIN 1 {property} Return the minimal value of a property, whether it is a string, number or NULL.
MAX REDUCE MAX 1 {property} Return the maximal value of a property, whether it is a string, number or NULL.
AVG REDUCE AVG 1 {property} Return the average value of a numeric property. This is equivalent to reducing by sum and count, and later on applying the ratio of them as an APPLY step.
STDDEV REDUCE STDDEV 1 {property} Return the standard deviation of a numeric property in the group.
QUANTILE REDUCE QUANTILE 2 {property} {quantile} Return the value of a numeric property at a given quantile of the results. Quantile is expressed as a number between 0 and 1.
TOLIST REDUCE TOLIST 1 {property} Merge all distinct values of a given property into a single array.
FIRST_VALUE REDUCE FIRST_VALUE {nargs} {property} [BY {property} [ASC|DESC]] Return the first or top value of a given property in the group, optionally by comparing that or another property.
RANDOM_SAMPLE REDUCE RANDOM_SAMPLE {nargs} {property} {sample_size} Perform a reservoir sampling of the group elements with a given size, and return an array of the sampled items with an even distribution.

5.5 APPLY functions

List of numeric APPLY functions
Function Description
log(x) Return the logarithm of a number, property or sub-expression
abs(x) Return the absolute number of a numeric expression
ceil(x) Round to the smallest value not less than x
floor(x) Round to largest value not greater than x
log2(x) Return the logarithm of x to base 2
exp(x) Return the exponent of x
sqrt(x) Return the square root of x
List of string APPLY functions
Function Description
upper(s) Return the uppercase conversion of s
lower(s) Return the lowercase conversion of s
substr(s, offset, count) Return the substring of s, starting at offset and having count characters. If offset is negative, it represents the distance from the end of the string. If count is -1, it means "the rest of the string starting at offset".
format( fmt, ...) Use the arguments following fmt to format a string. Currently the only format argument supported is %s and it applies to all types of arguments.
matched_terms([max_terms=100]) Return the query terms that matched for each record (up to 100), as a list. If a limit is specified, we will return the first N matches we find - based on query order.
split(s, [sep=","], [strip=" "]) Split a string by any character in the string sep, and strip any characters in strip. If only s is specified, we split by commas and strip spaces. The output is an array.
List of date/time APPLY functions
Function Description
timefmt(x, [fmt]) Return a formatted time string based on a numeric timestamp value x.
parsetime(timesharing, [fmt]) The opposite of timefmt() - parse a time format using a given format string.
day(timestamp) Round a Unix timestamp to midnight (00:00) start of the current day.
hour(timestamp) Round a Unix timestamp to the beginning of the current hour.
minute(timestamp) Round a Unix timestamp to the beginning of the current minute.
month(timestamp) Round a unix timestamp to the beginning of the current month.
dayofweek(timestamp) Convert a Unix timestamp to the day number (Sunday = 0).
dayofmonth(timestamp) Convert a Unix timestamp to the day of month number (1 .. 31).
dayofyear(timestamp) Convert a Unix timestamp to the day of year number (0 .. 365).
year(timestamp) Convert a Unix timestamp to the current year (e.g. 2018).
monthofyear(timestamp) Convert a Unix timestamp to the current month (0 .. 11).

6 Synonyms

Redis allows the use of synonym words for the searches. These synonyms are stored in a synonyms data structure. The synonym data structure is a set of gorups, with each gorup containing a list of words, which are synonyms. An example of such structure is:

    {boy, child, baby}
    {girl, child, baby}
    {man, adult, person}

When searching in Redis with FT.SEARCH, any matching words in the synonym list will be returned as result, as well as the original word. Using the synonyms table the search of the term 'child', which is not in the table, gives:


Redis search using synonyms

FT.SEARCH table child
1) (integer) 2
2) "index1"
3) 1) "name"
   2) "boy"
4) "index2"
5) 1) "name"
   2) "girl"

As seen, when the synonyms data structure contains a given group of synonyms, performing a query will return any document that contains a synonym in the list.

6.1 Adding synonyms

In order to add synonyms to the index, the command FT.SYNADD is used. the syntax of this command is as follows:

    FT.SYNADD <index name> <term1> <term2> ...

The command adds the given synonyms, passed on as individual strings, to the table (< index name>). It ouputs the index of the synonyms group, in order to use it later if the list wants to be updated.

It is to note that only the documents indexed after the addition of the synonyms will be affected by these. Therefore, a document added after will not be included in the search if synonyms want do be used.


Example of synonyms addition

FT.SYNADD table boy child baby
(integer) 0

6.2 Updating synonyms

Synonym groups can be updated with new words. Words cannot be removed from a synonym group. The command used to add new words to a synonyms group is FT.SYNUPDATE, as seen below.

    FT.SYNUPDATE <index name> <synonym group id> <term1> <term2> ...

The command updates the according synonym group, adding the given words.

As with SYNADD, only the documents indexed after the addition of new words will be affected by these. This means that new words of the synonym group will only be taken into account for documents indexed after these new words are added to the synonyms group.


Example of synonyms update

FT.SYNADD table boy child baby
FT.SYNUPDATE table 0 man
(integer) 0 

6.3 Viewing all the synonym groups

If one desires to see the synonym groups that are stored in the synonyms data structure at any given time, the commad FT.SYNDUMP can be used, as follows.

    FT.SYNDUMP <index name>

The command returns a list of the separate synonym words, along with the respective group id, of all the synonym groups the word belongs to.


Example of synonyms dump

FT.SYNADD table boy child baby
FT.SYNADD table girl child baby
FT.SYNUPDATE table 0 man
(integer) 0
(integer) 1
1) "man"
2) 1) (integer) 0
3) "girl"
4) 1) (integer) 1
5) "baby"
6) 1) (integer) 0
   2) (integer) 1
7) "child"
8) 1) (integer) 0
   2) (integer) 1
9) "boy"
10) 1) (integer) 0

7 RediSearch useful commands

7.1 What RediSearch stores in Redis

As RediSearch's module uses Redis' key-value structure, it must store all the information of the Indexes and the Suggestions in a key-value pair. In this section, we will try to understand how RediSearch stores the information.

First, create a new index in RediSearch:

FT.CREATE deister_cars SCHEMA model TEXT power NUMERIC

Now use the command keys to obtain if RediSearch has stored a new key in Redis.

KEYS *deister_cars*
1) "idx:deister_cars"

RediSearch has stored a key idx:deister_cars for the newly created index.

If the type of this key is inspected we can see the following:

TYPE idx:deister_cars

As we can see, the type of the value is a ft_index0. This type is not a native type, and is imported from the RediSearch module. Therefore, the value of this key must never be changed manually.

Now let's store a new car in the index:

FT.ADD deister_cars deisterCar1 1.0 FIELDS model Tesla power 170

And search for what keys Redis has created for this new entry in the index.

1) "idx:deister_cars"
2) "ft:deister_cars/tesla"
3) "nm:deister_cars/power"
4) "deisterCar1"

Now RediSearch has created three new keys for a single document!

If one takes a look into the types of these keys:

Copy> type ft:deister_cars/tesla
ft_invidx> type nm:deister_cars/power
numericdx> type deisterCar1

The types of the keys prefixed with ft and nm are ft_invidx and numericdx. Once again, these types are not native types and Redis cannot read them using GET, HGET, SGET... These types are compressed metadata information about the document that we just stored.

However, the key deisterCar1 is of hash type. This type of value can be read by Redis!. Let's read the value using the command HGETALL.

Copy> HGETALL deisterCar1
1) "model"
2) "Tesla"
3) "power"
4) "170"

RediSearch has stored in a hash key-value pair the information of the document.

Please note that despite being a native type, this key-value pair must not be manually changed.

7.2 Listing all existing indexes in Redis

Now that we know what RediSearch stores in Redis when we create a new index, we can use this information to get a list of all existing indexes.

Using FT._LIST

This command is available since RediSearch 2.0 and will be documented as soon as possible.

Using KEYS.

Since we know that Redis stores all indexes as idx:.... we can use this to get a list of all existing indexes with:

KEYS idx:*

This will output a list of all keys containing idx:* in the name, and therefore a list of all our indexes.