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.
