All eyes on AI: 2026 predictions The shifts that will shape your stack.

Read now
For developersHow to Search Movies Database with Redis
In this tutorial, you'll learn how to use Redis Search to index and query a movies database. You'll start with basic data modeling, create search indexes, run queries, and work your way up to advanced aggregations and a sample application.

#Prerequisites

Before starting, make sure you have Redis running. You can follow the Redis quick start guide to set up Redis using Docker, Redis Cloud, or other methods.
For this tutorial, the quickest way is to use Docker:
Note: The container will automatically be removed when it exits (--rm parameter).

#Data Modeling

#Sample Dataset

In this tutorial, you'll work with a simple dataset describing movies. A movie is represented by the following attributes:
  • movie_id: The unique ID of the movie, internal to this database
  • title: The title of the movie
  • plot: A summary of the movie
  • genre: The genre of the movie (single genre per movie for simplicity)
  • release_year: The year the movie was released as a numerical value
  • rating: A numeric value representing the public's rating for this movie
  • votes: Number of votes
  • poster: Link to the movie poster
  • imdb_id: ID of the movie in the IMDB database

#Key Structure

A common way of defining keys in Redis is to use specific patterns. For this application, we'll use:
  • business_object:key
For example:
  • movie:001 for the movie with the id 001
  • user:001 for the user with the id 001

#Data Structure

For movie information, we'll use a Redis Hash. A Redis Hash allows the application to structure all the movie attributes in individual fields, and Redis Search will index these fields based on the index definition.

#Insert Sample Data

Let's add some movies to the database using redis-cli or Redis Insight.
Connect to your Redis instance and run the following commands:
Now you can retrieve information from the hash using the movie ID:
Output:
You can also increment the rating:
Output:
But how do you find movies by year of release, rating, or title? This is where Redis Search comes in.

#Create a Search Index

Redis Search provides a simple and automatic way to create secondary indices on Redis Hashes.
Redis Search Indexing
When using Redis Search, you must first index the fields you want to query. Let's index:
  • Title
  • Release Year
  • Rating
  • Genre

#Create the Index

Let's break down this command:
  • FT.CREATE: Creates an index with the given spec
  • idx:movie: The name of the index
  • ON hash: The type of structure to be indexed
  • PREFIX 1 "movie:": Index all keys starting with movie:. You can specify multiple prefixes, e.g., PREFIX 2 "movie:" "tv_show:"
  • SCHEMA ...: Defines the schema with field types:
    • TEXT: Full-text searchable fields (tokenized and stemmed)
    • NUMERIC: Numeric fields for range queries
    • TAG: Exact match fields
    • SORTABLE: Enables sorting on the field
Inspect the index:
Warning: Do not index all fields
Indexes take space in memory and must be updated when the primary data is updated. Create indexes carefully and only for fields you need to query.

#Basic Queries

Now let's run some queries using FT.SEARCH.

#Text Search

Find all movies containing "war":
Output:
The movie "Star Wars" is found even though you searched for "war" because the title is indexed as TEXT, meaning it's tokenized and stemmed.

#Limiting Returned Fields

Use RETURN to specify which fields to return:
Output:

#Field-Specific Search

Use @field: syntax to search specific fields:

#Negation

Use - to exclude terms:
Output:

#Fuzzy Matching

Output:

#TAG Filters

The genre field is indexed as a TAG for exact match queries:
Output:
Multiple TAG values (OR):
Learn more about Tag filters.

#Combined Conditions

Thriller or Action movies without "Jedi" in the title:

#Numeric Range Queries

Movies released between 1970 and 1980:
Using FILTER parameter:
Using query string:
Exclude a value with (:

#Index Management

#List All Indexes

Output:

#Inspect an Index

This returns detailed information about the index including field definitions and document count.

#Add Fields to an Index

Use FT.ALTER to add new fields:
The WEIGHT parameter declares the importance of this field when calculating result accuracy (default is 1). Here, the plot is weighted less than the title.
Now you can search the plot field:

#Drop an Index

Note: Dropping an index does not delete the underlying data. The movie hashes remain in the database.
Verify the data still exists:
Output:
Tip: Add the DD parameter to FT.DROPINDEX to also delete the indexed documents.

#Working with Documents

Redis Search automatically indexes new, updated, and deleted documents.

#Insert and Auto-Index

Output: 1) (integer) 4
Output: 1) (integer) 5
The new movie is automatically indexed:

#Update Documents

Output:

#Document Expiration

When a document expires (TTL), it's automatically removed from the index:
After 20 seconds:
Output: 1) (integer) 0
Tip: This is useful for "Ephemeral Search" use cases like caching, session content, etc.

#Import Full Dataset

Now let's import a larger dataset to explore more advanced features.

#Dataset Overview

We'll import three datasets:
DatasetRecordsDescription
Movies922Movie hashes with title, plot, genre, rating, etc.
Theaters117New York theater locations with geospatial data
Users5,996User profiles with demographics and login data
Movie fields: movie:id (key), title, plot, genre, release_year, rating, votes, poster, imdb_id
Theater fields: theater:id (key), name, address, city, zip, phone, url, location (longitude,latitude for geo queries)
User fields: user:id (key), first_name, last_name, email, gender, country, country_code, city, longitude, latitude, last_login (EPOC timestamp), ip_address

#Import the Data

First, flush the database:
Then import using redis-cli:
Verify the import:
Output:
Output:
Output:
Use DBSIZE to see the total number of keys.

#Create Production Indexes

Movies Index:
Verify with FT.INFO "idx:movie" - should show 922 documents.
Theaters Index (with Geospatial):
Verify with FT.INFO "idx:theater" - should show 117 documents.
Users Index:

#Advanced Queries

With the full dataset, let's explore more advanced query techniques.

#Conditions

Find all movies containing "heat" (in title or plot):
This returns 4 movies because:
  • It searches all TEXT fields (title and plot)
  • It finds related words like "heated" due to stemming
  • Results are sorted by score (title has weight 1.0, plot has 0.5)
Search only in title:
Returns only 2 movies.
Title contains "heat" but NOT "california":
Returns 1 movie ("Heat").
Note: Without parentheses, -california applies to ALL text fields:

#Aggregations

Beyond retrieving documents, you often need to aggregate data. Redis provides FT.AGGREGATE for this.

#Group By & Sort By

Number of movies by year:
Number of movies by year (descending):
Movies by genre with total votes and average rating:
Count female users by country:

#Apply Functions

Number of logins per year and month:
Logins by day of week:

#Filter Expressions

Use FILTER to filter results after aggregation.
Female users by country (except China, with more than 100 users):
Logins per month for year 2020:

#Advanced: Filtered Indexes

You can create indexes with FILTER expressions to index only a subset of documents.
Create an index for Drama movies from the 1990s:
Run FT.INFO idx:drama to see the index definition and statistics.
Notes:
  • The PREFIX is required even when using FILTER
  • This index is useful for specialized queries but may be redundant with idx:movie
Verify both indexes return the same count:
Output: 1) (integer) 24
Output: 1) (integer) 24

#Sample Application

Now let's run a complete sample application that demonstrates Redis Search in action.

#Clone the Repository

#Run with Docker Compose

This starts:
  1. Redis on port 6380 with all data and indexes
  2. Java REST Service on port 8085
  3. Node REST Service on port 8086
  4. Python REST Service on port 8087
  5. Frontend on port 8084

#Access the Application

#Cleanup

Stop and remove all containers:

#References