Redis Search

Redis Search, also called the Redis Query Engine, adds indexes and a query language to Redis. Instead of fetching a key by its exact name, you can ask questions such as "Find all users in Pune aged 25 to 35" or "Find articles that contain the word cache." Redis answers in milliseconds.

The Book Index Analogy

A thick book has an index at the back. You look up a word and jump straight to the right pages without reading every page. A Redis Search index works the same way. It builds a lookup table over your fields, so queries skip the full scan.

  Without index                     With index
  Check user:1, user:2, user:3 ...  Index: city=Pune → user:1, user:7, user:9
  (visit every key)                 (jump straight to matches)

Step 1: Store Some Data

127.0.0.1:6379> HSET user:1 name "Asha Verma" age 29 city "Pune"
(integer) 3
127.0.0.1:6379> HSET user:2 name "Ravi Kumar" age 41 city "Delhi"
(integer) 3
127.0.0.1:6379> HSET user:3 name "Meena Rao" age 33 city "Pune"
(integer) 3

Step 2: Create an Index

127.0.0.1:6379> FT.CREATE idx:users ON HASH PREFIX 1 user: SCHEMA name TEXT age NUMERIC city TAG
OK

The command tells Redis to watch every Hash whose key starts with user: and to index three fields. Existing keys join the index automatically, and new keys join as you add them.

Field Type   Use It For                     Query Style
───────────  ─────────────────────────────  ───────────────────
TEXT         Words and sentences            @name:Asha
NUMERIC      Numbers and ranges             @age:[25 35]
TAG          Exact labels such as a city    @city:{Pune}
GEO          Longitude and latitude         @loc:[77.2 28.6 10 km]
VECTOR       Embeddings for similarity      See the vector search topic

Step 3: Search

127.0.0.1:6379> FT.SEARCH idx:users "@city:{Pune}"
1) (integer) 2
2) "user:1"
3) 1) "name"
   2) "Asha Verma"
   3) "age"
   4) "29"
   5) "city"
   6) "Pune"
4) "user:3"
5) 1) "name"
   2) "Meena Rao"
   ...

The first number tells you the total match count. Each match follows with its key name and fields.

Combining Conditions

Query                                   Meaning
──────────────────────────────────────  ─────────────────────────────────
@city:{Pune} @age:[30 50]               Pune AND age 30 to 50
@city:{Pune|Delhi}                      Pune OR Delhi
@name:Asha                              Name contains the word Asha
@name:Ash*                              Name has a word starting with Ash
-@city:{Delhi}                          Anything except Delhi

A space between conditions means AND. A pipe inside braces means OR. A minus sign negates a condition.

Sorting, Limiting, and Returning Fields

127.0.0.1:6379> FT.SEARCH idx:users "@city:{Pune}" SORTBY age DESC LIMIT 0 10 RETURN 2 name age

SORTBY orders the results and LIMIT sets the page. RETURN lists the fields to send, which cuts network use.

Aggregations for Reports

FT.AGGREGATE groups and calculates, similar to GROUP BY in SQL.

127.0.0.1:6379> FT.AGGREGATE idx:users "*" GROUPBY 1 @city REDUCE COUNT 0 AS total

This query counts users per city.

Indexing JSON Documents

FT.CREATE idx:books ON JSON PREFIX 1 book: SCHEMA $.title AS title TEXT $.pages AS pages NUMERIC

The AS keyword gives each JSON path a short field name for queries.

Managing Indexes

FT.INFO idx:users              → shows index size and settings
FT.DROPINDEX idx:users         → deletes the index and keeps the data
FT._LIST                       → lists all indexes

Practical Example – Course Search Box

Each course is a JSON document with title, level, and rating.

User types "cache" and picks "Beginner":
  FT.SEARCH idx:courses "@title:cache @level:{Beginner}" SORTBY rating DESC LIMIT 0 5

Redis returns the five best-rated beginner courses that mention cache.

Key Points

  • FT.CREATE builds an index over Hashes or JSON documents.
  • TEXT, NUMERIC, TAG, GEO, and VECTOR fields support different query styles.
  • FT.SEARCH finds documents and FT.AGGREGATE builds summaries.
  • An index uses extra memory, so index only the fields you query.