[Avg. reading time: 20 minutes]

Redis Search

Redis Search (or RediSearch) is a full-text search and secondary indexing engine for Redis. It allows for performing complex searches and filtering over the data stored in Redis without needing a relational database. This powerful module enables advanced querying capabilities like full-text search, filtering, aggregation, and auto-complete.

Key Features

Full-text Search: Perform text searches with support for stemming, phonetic matching, and ranked retrieval.

Secondary Indexing: Create indexes for quick lookup of data stored in Redis.

Complex Querying: Supports boolean logic, fuzzy matching, numeric filtering, and geospatial querying.

Autocomplete: Typeahead and autocomplete functionalities for building responsive applications.

Faceted Search and Aggregation: Aggregate results and perform statistical queries like grouping and sorting.

Use Cases

E-commerce Platforms:

Search through product descriptions, tags, and categories.

Use filters like price, category, or brand with full-text search for a better user experience.

Content Management Systems:

Implement full-text search for articles, blogs, and documents.

Provide auto-complete for faster and more user-friendly search results. Log and Event Analysis:

Search and filter through logs stored in Redis.

Perform real-time querying and analytics for log monitoring systems.

Geospatial Applications:

Combine geospatial search (e.g., find nearby stores) with text search capabilities. Ideal for applications like food delivery or finding services near a user location.

Chat and Messaging Applications:

Index and search chat messages.

Allow searching through conversations with fuzzy matching and keyword highlights.

User Profiles and Recommendations:

Search user attributes or interests to provide personalized content or recommendations.

Quickly index and lookup attributes like hobbies, location, and preferences.

flushdb
JSON.SET friends:character:ross $ '{
  "name": "Ross Geller",
  "occupation": "Paleontologist",
  "relationship_status": "Divorced",
  "friends": ["Rachel Green", "Monica Geller", "Joey Tribbiani", "Chandler Bing", "Phoebe Buffay"],
  "children": [
    {
      "name": "Ben Geller",
      "mother": "Carol Willick"
    },
    {
      "name": "Emma Geller-Green",
      "mother": "Rachel Green"
    }
  ],
  "education": {
    "college": "Columbia University",
    "degree": "Ph.D. in Paleontology"
  }}'

JSON.SET friends:character:monica $ '{
  "name": "Monica Geller",
  "occupation": "Chef",
  "relationship_status": "Married",
  "friends": ["Ross Geller", "Rachel Green", "Joey Tribbiani", "Chandler Bing", "Phoebe Buffay"],
  "spouse": "Chandler Bing",
  "education": {
    "culinary_school": "Not specified"
  },
  "employment_history": [
    {
      "company": "Alessandro\'s",
      "position": "Head Chef",
      "years": "Not specified"
    },
    {
      "company": "Javu",
      "position": "Chef",
      "years": "Not specified"
    }
  ]}'

JSON.SET friends:character:chandler $ '{
  "name": "Chandler Bing",
  "occupation": "Statistical analysis and data reconfiguration",
  "relationship_status": "Married",
  "friends": ["Ross Geller", "Monica Geller", "Joey Tribbiani", "Rachel Green", "Phoebe Buffay"],
  "spouse": "Monica Geller",
  "education": {
    "college": "Not specified"
  }}'

JSON.SET friends:character:phoebe $ '{
  "name": "Phoebe Buffay",
  "occupation": "Masseuse and Musician",
  "relationship_status": "Married",
  "friends": ["Ross Geller", "Monica Geller", "Joey Tribbiani", "Chandler Bing", "Rachel Green"],
  "spouse": "Mike Hannigan",
  "education": {
    "high_school": "Not completed"
  }}'

JSON.SET friends:character:joey $ '{
  "name": "Joey Tribbiani",
  "occupation": "Actor",
  "relationship_status": "Single",
  "friends": ["Ross Geller", "Monica Geller", "Chandler Bing", "Rachel Green", "Phoebe Buffay"],
  "education": {
    "drama_school": "Not specified"
  },
  "employment_history": [
    {
      "show": "Days of Our Lives",
      "role": "Dr. Drake Ramoray",
      "years": "Various"
    }
  ]}'

JSON.SET friends:guest:janice $ '{
  "name": "Janice Litman Goralnik",
  "occupation": "Unknown",
  "relationship_status": "Divorced",
  "catchphrase": "Oh. My. God!",
  "friends": ["Chandler Bing"],
  "appearances": [
    {
      "season": 1,
      "episode": 5
    },
    {
      "season": 2,
      "episode": 3
    },
    {
      "season": 3,
      "episode": 8
    },
    {
      "season": 4,
      "episode": 13
    },
    {
      "season": 5,
      "episode": 11
    },
    {
      "season": 7,
      "episode": 7
    },
    {
      "season": 10,
      "episode": 15
    }
  ]}'

JSON.SET friends:guest:gunther $ '{
  "name": "Gunther",
  "occupation": "Chef",
  "relationship_status": "Single",
  "workplace": "Central Perk",
  "crush": "Rachel Green",
  "friends": ["Rachel Green", "Joey Tribbiani", "Monica Geller", "Ross Geller", "Phoebe Buffay", "Chandler Bing"],
  "appearances": [
    {
      "season": 1,
      "episode": 2
    },
    {
      "season": 2,
      "episode": 18
    },
    {
      "season": 3,
      "episode": 7
    },
    {
      "season": 5,
      "episode": 2
    },
    {
      "season": 6,
      "episode": 9
    },
    {
      "season": 7,
      "episode": 4
    }
  ]}'

For searching first you have to create INDEXES

FT.CREATE {index_name} ON JSON SCHEMA {json_path} AS {attribute} {type}
  • <indexName>: The name of the index you are creating.
  • [ON <structure>]: Specifies the data structure to index, which can be HASH (default) or JSON if you're indexing JSON documents with RedisJSON.
  • [PREFIX count <prefix> ...]: Defines one or more key prefixes. Only keys that match the prefix(es) will be indexed.
  • SCHEMA: Followed by one or more field definitions.
  • <field>: The name of the field to index.
  • <type>: The type of the field (TEXT, NUMERIC, GEO, or TAG).
FT.CREATE idx:friends ON JSON PREFIX 1 friends:character: SCHEMA $.name AS name TEXT $.occupation AS occupation TEXT $.relationship_status AS relationship_status TAG

Explanation

idx:friends: Create an index named idx:friends.

ON JSON: Apply this index to JSON documents.

PREFIX 1 friends:character:: Only index keys with this prefix.

SCHEMA: Defines the structure of the index.
$.name AS name TEXT: Index the "name" attribute for full-text search.
$.occupation AS occupation TEXT: Index the "occupation" attribute for full-text search.
$.relationship_status AS relationship_status TAG: Index the "relationship_status" attribute for efficient categorical filtering.
FT.SEARCH idx:friends "@occupation:Chef"

This will return

  • Total Number of search results.
  • Key of the document.
  • Key value pairs representing the JSON content.
    • $ means entire document
    • contains the all the details

Can I have PREFIX 2?

FT.CREATE idx:friends_guests ON JSON PREFIX 2 friends:character: friends:guest: SCHEMA $.name AS name TEXT $.occupation AS occupation TEXT $.relationship_status AS relationship_status TAG

Now running the query against friends_guests, you will notice 2 docs.

FT.SEARCH idx:friends_guests "@occupation:Chef"

To find all characters who are Married

FT.SEARCH idx:friends "@relationship_status:{Married}"

What happens when you search on columns not indexed?

FT.SEARCH idx:friends "@college:Columbia University"

Recreate the Index

FT.DROPINDEX idx:friends

FT.CREATE idx:friends ON JSON PREFIX 1 friends:character: SCHEMA $.name AS name TEXT $.occupation AS occupation TEXT $.relationship_status AS relationship_status TAG $.education.college AS college TEXT
FT.CREATE idx:occupation ON JSON PREFIX 1 "friends:character:" SCHEMA $.occupation AS occupation TEXT
FT.SEARCH idx:occupation "*"

FT.SEARCH idx:occupation "Chef"
FT.INFO idx:occupation

Auto Suggestion with Fuzzy Logic

SUGADD : Autocomplete suggestion dictionary in Redis Search.

last column is the score. Higher scores mean high priority in suggestion.

FT.SUGADD idx:friends_names "Ross Geller" 2
FT.SUGADD idx:friends_names "Rachel Green" 2
FT.SUGADD idx:friends_names "Monica Geller" 2
FT.SUGADD idx:friends_names "Chandler Bing" 2
FT.SUGADD idx:friends_names "Phoebe Buffay" 2
FT.SUGADD idx:friends_names "Joey Tribbiani" 2
FT.SUGADD idx:friends_names "Gunther" 1
FT.SUGADD idx:friends_names "Janice" 1
FT.SUGGET idx:friends_names "Ro" FUZZY WITHSCORES

Now using Fuzzy logic, it determines Ross Geller sounds more closer than other names. Fuzzy option allows slight misspellings, typos giving more flexibility.

1) "Ross Geller"
2) "0.6324555277824402"
3) "Rachel Green"
4) "0.08161024749279022"
5) "Monica Geller"
6) "0.07813586294651031"
7) "Joey Tribbiani"
8) "0.07507050782442093"

Now lets try without Fuzzy

FT.SUGGET idx:friends_names "Ro"

#Search #NoSQL #RedisVer 5.5.3

Last change: 2025-10-15