{"id":21672478,"url":"https://github.com/redis-developer/demo-movie-app-redisearch-java","last_synced_at":"2026-05-05T20:33:40.069Z","repository":{"id":100135802,"uuid":"345868728","full_name":"redis-developer/demo-movie-app-redisearch-java","owner":"redis-developer","description":"A demo movie app that show cases Redisearch. Written in Java","archived":false,"fork":false,"pushed_at":"2023-06-30T21:38:01.000Z","size":13021,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-01-25T09:27:37.220Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redis-developer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-09T03:15:56.000Z","updated_at":"2024-03-26T04:26:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"2426e186-bea2-430d-a033-b70b19c16775","html_url":"https://github.com/redis-developer/demo-movie-app-redisearch-java","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-developer%2Fdemo-movie-app-redisearch-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-developer%2Fdemo-movie-app-redisearch-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-developer%2Fdemo-movie-app-redisearch-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-developer%2Fdemo-movie-app-redisearch-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redis-developer","download_url":"https://codeload.github.com/redis-developer/demo-movie-app-redisearch-java/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244576933,"owners_count":20475214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T13:29:26.539Z","updated_at":"2026-05-05T20:33:40.022Z","avatar_url":"https://github.com/redis-developer.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Movie Database app in Java andRedis Search\n\nThe goal of this application is to show how to develop aRedis Searchapplication with Java. This project is a Spring Boot application.\nThis application uses [JRedis Search](https://github.com/RediSearch/JRediSearch) that is based on [Jedis](https://github.com/xetorthio/jedis).\nThis application exposes various endpoint that are directly consumable in a front end.\n\n\n## Technical Stack\n\n- Frontend: Vue.js, Javascript\n- Backend: Redis\n\n## How it works?\n### Main page\n\n***Example: Get 'Action' Movies released in 2015-2020 and sort by Rating desc***\n\nSelect necessary parameters from a dropdown lists via UI;\n\nRedisearch query:\n```\n\u003e FT.SEARCH idx:movie \"@genre:{Action} @release_year:[2015 2020] SORTBY rating desc\"\n```\n___\n### Basic Search\n\n![basic_search.png](https://raw.githubusercontent.com/redis-developer/demo-movie-app-redisearch-java/master/docs/basic_search.png)\n\nEnter any search string for the movie database for example ```@genre:{Drama} @release_year:[1990 1995]```\n\n**Some Sample Queries**:\n\n***Fuzzy Search 'empre', for 'Empire''***\n\nSearch: ```%empre%```\n\n```\n\u003e FT.SEARCH idx:movie \"%empre% \"\n```\n\n***All 'Action' Movies***\n\nSearch: ```@genre:{Action}```\n\n```\n\u003e FT.SEARCH idx:movie \"@genre:{Action} \"\n```\n\n***All movies relaesed in 2000***\n\nSearch: ```@release_year:[2000 2000]```\n\n```\n\u003e FT.SEARCH idx:movie \"@release_year:[2000 2000] \"\n```\n\n***'Drama' from 2010 to 2020***\n\nSearch: ```@genre:{Drama} @release_year:[2010 2020]```\n\n```\n\u003e FT.SEARCH idx:movie \"@genre:{Drama} @release_year:[2010 2020] \"\n```\n\n***Star Wars Movies***\n\nSearch: ```star wars```\n\n```\n\u003e FT.SEARCH idx:movie \"star wars \"\n```\n\n***Star Wars movies that does not mention Jedi***\n\nSearch: ```star wars -jedi```\n\n```\n\u003e FT.SEARCH idx:movie \"star wars -jedi \"\n```\n___\n\n### Faceted Search\n\n![faceted_search.png](https://raw.githubusercontent.com/redis-developer/demo-movie-app-redisearch-java/master/docs/faceted_search.png)\n\n**Example : *All the movies that contains the string \"`war`\"***\n\nSearch: ```war```\nRelease years: 1960-2020\nRating: 0-10\n\nRedisearch query:\n\n```\n\u003e FT.SEARCH idx:movie \"war @release_year:[1960 2020] @rating:[0 10] \"\n1) (integer) 2\n2) \"movie:11005\"\n3)  1) \"title\"\n    2) \"Star Wars: Episode VI - Return of the Jedi\"\n    ...\n   14) \"tt0086190\"\n4) \"movie:11002\"\n5)  1) \"title\"\n    2) \"Star Wars: Episode V - The Empire Strikes Back\"\n    ...\n   13) \"imdb_id\"\n   14) \"tt0080684\"\n```\n\nThe FT.SEARCH commands returns a list of results starting with the number of results, then the list of elements (keys \u0026 fields).\n\nAs you can see the movie *Star Wars: Episode V - The Empire Strikes Back* is found, even though you used only the word “war” to match “Wars” in the title. This is because the title has been indexed as text, so the field is [tokenized](https://oss.redislabs.com/redisearch/Escaping/) and [stemmed](https://oss.redislabs.com/redisearch/Stemming/).\n\n---\n**Example : *All the movies that contains the string \"`war` but NOT the `jedi` one\"***\n\nSearch: ```war -jedi```\n\nRelease years: 1960-2020\n\nRating: 0-10\n\nAdding the string `-jedi` (minus) will ask the query engine not to return values that contain `jedi`.\n\nRedisearch query:\n```\n\u003e FT.SEARCH idx:movie \"war -jedi @release_year:[1960 2020] @rating:[0 10]\"\n1) (integer) 1\n2) \"movie:11002\"\n3) 1) \"title\"\n   2) \"Star Wars: Episode V - The Empire Strikes Back\"\n   3) \"release_year\"\n   4) \"1980\"\n```\n\n---\n**Example : *All the movies that contains the string \"`gdfather` using fuzzy search\"***\n\n**Search**: ```%gdfather%```\n\nRelease years: 1960-2020\n\nRating: 0-10\n\nAs you can see the word godfather contains a speelling error, it can however be matched using [fuzzy matching](https://oss.redislabs.com/redisearch/Query_Syntax/#fuzzy_matching). Fuzzy matches are performed based on [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) (LD).\n\nRedisearch query:\n\n```\n\u003e FT.SEARCH idx:movie \"%gdfather% @release_year:[1960 2020] @rating:[0 10] \"\n1) (integer) 1\n2) \"movie:11003\"\n3) 1) \"title\"\n   2) \"The Godfather\"\n   3) \"release_year\"\n   4) \"1972\"\n```\n\n---\n**Example  : *All `Thriller` movies\"***\n\nThe `genre` fields is indexed as a TAG and allows exact match queries.\n\nThe syntax to query a TAG field is  @field_name:{value}\n\nSearch: ```@genre:{Thriller}```\n\nRelease years: 1960-2020\n\nRating: 0-10\n\nRedisearch query:\n```\n\u003e FT.SEARCH idx:movie \"@genre:{Thriller}\" @release_year:[1960 2020] @rating:[0 10]\n1) (integer) 1\n2) \"movie:11004\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"release_year\"\n   4) \"1995\"\n```\n\n---\n**Example : *All `Thriller` or `Action` movies\"***\n\nSearch: ```@genre:{Thriller|Action}```\n\nRelease years: 1960-2020\n\nRating: 0-10\n\nRedisearch query:\n\n```\n\u003e FT.SEARCH idx:movie \"@genre:{Thriller|Action}\" @release_year:[1960 2020] @rating:[0 10]\n1) (integer) 3\n2) \"movie:11004\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"release_year\"\n   4) \"1995\"\n4) \"movie:11005\"\n5) 1) \"title\"\n   2) \"Star Wars: Episode VI - Return of the Jedi\"\n   3) \"release_year\"\n   4) \"1983\"\n6) \"movie:11002\"\n7) 1) \"title\"\n   2) \"Star Wars: Episode V - The Empire Strikes Back\"\n   3) \"release_year\"\n   4) \"1980\"\n```\n\nYou can find more information about the Tag filters in [the documentation](https://oss.redislabs.com/redisearch/master/Query_Syntax/#tag_filters).\n\n---\n**Example : *All `Thriller` or `Action` movies that does not have `Jedi` in the title\"***\n\nSearch: ```@genre:{Thriller|Action} @title:-jedi```\n\nRelease years: 1960-2020\n\nRating: 0-10\n\nRedisearch query:\n\n```\n\u003e FT.SEARCH idx:movie \"@genre:{Thriller|Action} @title:-jedi\" @release_year:[1960 2020] @rating:[0 10]\n1) (integer) 2\n2) \"movie:11004\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"release_year\"\n   4) \"1995\"\n4) \"movie:11002\"\n5) 1) \"title\"\n   2) \"Star Wars: Episode V - The Empire Strikes Back\"\n   3) \"release_year\"\n   4) \"1980\"\n```\n\n---\n\n### How the data is stored:\n\nAs a Redis developer, one of the first things to look when building your application is to define the structure of the key and data (data design/data modeling).\n\nA common way of defining the keys in Redis is to use specific patterns in them. For example in this application where the database will probably deal with various business objects: movies, actors, theaters, users, ... we can use the following pattern:\n\n* `business_object:key`\n\nFor example:\n* `movie:001` for the movie with the id 001\n* `user:001` the user with the id 001\n\n\nand for the movies information you should use a Redis [Hash](https://redis.io/topics/data-types#hashes).\n\nA Redis Hash allows the application to structure all the movie attributes in individual fields; alsoRedis Searchwill index the fields based on the index definition.\n\n\n**Movies**\n\nThe file `/redisearch-docker/dataset/import_movies.redis` is a script that creates 922 Hashes.\n\nThe movie hashes contain the following fields.\n\n* **`movie:id`** : The unique ID of the movie, internal to this database (used as the key of the hash)\n* **`title`** : The title of the movie.\n* **`plot`** : A summary of the movie.\n* **`genre`** : The genre of the movie, for now a movie will only have a single genre.\n* **`release_year`** : The year the movie was released as a numerical value.\n* **`rating`** : A numeric value representing the public's rating for this movie.\n* **`votes`** : Number of votes.\n* **`poster`** : Link to the movie poster.\n* **`imdb_id`** : id of the movie in the [IMDB](https://imdb.com) database.\n\n\u003cdetails\u003e\n  \u003csummary\u003eSample Data: \u003cb\u003emovie:521\u003c/b\u003e\u003c/summary\u003e\n  \u003ctable\u003e\n      \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eField\u003c/th\u003e\n            \u003cth\u003eValue\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n        \u003cth\u003etitle\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        Spider-Man\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003eplot\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        When bitten by a genetically modified spider a nerdy shy and awkward high school student gains spider-like abilities that he eventually must use to fight evil as a superhero after tragedy befalls his family.\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003egenre\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        Action\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003erelease_year\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        2002\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003erating\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        7.3\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003evotes\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        662219\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003eposter\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        https://m.media-amazon.com/images/M/MV5BZDEyN2NhMjgtMjdhNi00MmNlLWE5YTgtZGE4MzNjMTRlMGEwXkEyXkFqcGdeQXVyNDUyOTg3Njg@._V1_SX300.jpg\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003eimdb_id\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        tt0145487\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctbody\u003e\n  \u003c/table\u003e\n\u003c/details\u003e\n\n**Actors**\n\nThe file `/redisearch-docker/dataset/import_actors.redis` is a script that creates 1319 Hashes.\n\nThe movie hashes contain the following fields.\n\n* **`actor:id`** : The unique ID of the actor\n* **`first_name`** : The first name of the actor.\n* **`last_name`** : The last name of the actor.\n* **`date_of_birth`** : The birth year of the actor\n\n\u003cdetails\u003e\n  \u003csummary\u003eSample Data: \u003cb\u003eactor:521\u003c/b\u003e\u003c/summary\u003e\n  \u003ctable\u003e\n      \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eField\u003c/th\u003e\n            \u003cth\u003eValue\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n        \u003cth\u003efirst_name\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        Renee\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003elast_name\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        Olstead\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003edate_of_birth\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        1989\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctbody\u003e\n  \u003c/table\u003e\n\u003c/details\u003e\n\n**Users**\n\nThe file `/redisearch-docker/dataset/import_users.redis` is a script that creates 5996 Hashes.\n\nThe user hashes contain the following fields.\n\n* **`user:id`** : The unique ID of the user.\n* **`first_name`** : The first name of the user.\n* **`last_name`** : The last name of the user.\n* **`email`** : The email of the user.\n* **`gender`** : The gender of the user (`female`/`male`).\n* **`country`** : The country name of the user.\n* **`country_code`** : The country code of the user.\n* **`city`** : The city of the user.\n* **`longitude`** : The longitude of the user.\n* **`latitude`** : The latitude of the user.\n* **`last_login`** : The last login time for the user, as EPOC time.\n* **`ip_address`** : The IP address of the user.\n\n\u003cdetails\u003e\n \u003csummary\u003eSample Data: \u003cb\u003euser:3233\u003c/b\u003e\u003c/summary\u003e\n  \u003ctable\u003e\n      \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eField\u003c/th\u003e\n            \u003cth\u003eValue\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n        \u003cth\u003efirst_name\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        Rosetta\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003elast_name\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        Olyff\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003eemail\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        rolyff6g@163.com\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003egender\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        female\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003ecountry\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        China\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003ecountry_code\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        CN\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003ecity\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        Huangdao\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003elongitude\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        120.04619\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003elatitude\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        35.872664\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003elast_login\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        1570386621\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth\u003eip_address\u003c/th\u003e\n        \u003ctd style='font-family:monospace; font-size: 0.875em; \"'\u003e\n        218.47.90.79\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctbody\u003e\n  \u003c/table\u003e\n\u003c/details\u003e\n\n### Create the Index\n\nCreate the index with the following command:\n\n```\n\u003e FT.CREATE idx:movie ON hash PREFIX 1 \"movie:\" SCHEMA title TEXT SORTABLE release_year NUMERIC SORTABLE rating NUMERIC SORTABLE genre TAG SORTABLE\n```\n\nBefore running some queries let's look at the command in detail:\n\n* [`FT.CREATE`](https://oss.redislabs.com/redisearch/master/Commands/#ftcreate) : creates an index with the given spec. The index name will be used in all the key names so keep it short.\n* `idx:movie` : the name of the index\n* `ON hash` : the type of structure to be indexed. *Note that inRedis Search2.0 only hash structures are supported, this parameter will accept other Redis data types in future asRedis Searchis updated to index them*\n* `PREFIX 1 \"movie:\"` : the prefix of the keys that should be indexed. This is a list, so since we want to only index movie:* keys the number is 1. Suppose you want to index movies and tv_show that have the same fields, you can use: `PREFIX 2 \"movie:\" \"tv_show:\"`\n* `SCHEMA ...`: defines the schema, the fields and their type, to index, as you can see in the command, we are using [TEXT](https://oss.redislabs.com/redisearch/Query_Syntax/#a_few_query_examples), [NUMERIC](https://oss.redislabs.com/redisearch/Query_Syntax/#numeric_filters_in_query) and [TAG](https://oss.redislabs.com/redisearch/Query_Syntax/#tag_filters), and [SORTABLE](https://oss.redislabs.com/redisearch/Sorting/) parameters.\n\nYou can find information about the [FT.CREATE](https://oss.redislabs.com/redisearch/Commands/#ftcreate) command in the [documentation](https://oss.redislabs.com/redisearch/Commands/#ftcreate).\n\n\nYou can look at the index information with the following command:\n\n```\n\u003e FT.INFO idx:movie\n```\n\n### How the data is accessed:\n\nOne of the goals ofRedis Searchis to provide rich querying capabilities such as:\n\n* simple and complex conditions\n* sorting\n* pagination\n* counting\n\n\n### Conditions\n\nThe best way to start to work withRedis Searchquery capabilities is to look at the various conditions options.\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003e\n  Find all the movies that contain the word 'heat' or related to 'heat'\n  \u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"heat\" RETURN 2 title plot\n\n1) (integer) 4\n2) \"movie:1141\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"plot\"\n   4) \"A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist.\"\n4) \"movie:818\"\n5) 1) \"title\"\n   2) \"California Heat\"\n   3) \"plot\"\n   4) \"A lifeguard bets he can be true to just one woman.\"\n6) \"movie:736\"\n7) 1) \"title\"\n   2) \"Chicago Justice\"\n   3) \"plot\"\n   4) \"The State's Attorney's dedicated team of prosecutors and investigators navigates heated city politics and controversy head-on,while fearlessly pursuing justice.\"\n8) \"movie:1109\"\n9) 1) \"title\"\n   2) \"Love \u0026 Hip Hop: Miami\"\n   3) \"plot\"\n   4) \"'Love and Hip Hop Miami' turns up the heat and doesn't hold back in making the 305 the place to be. Multi-platinum selling hip-hop legend Trick Daddy is back in the studio collaborating ...\"\n\n```\n\nThe first line contains the number of documents (`4`) that match the query condition, then the list of movies.\n\nThis query is a \"fieldless\" condition, this means that the query engine has:\n* searched in all the TEXT fields of the index(`title` and `plot`)\n* for the word `heat` and related words, this is why the movie:736 is returned since it has the word `heated` in the plot ([stemming](https://oss.redislabs.com/redisearch/Stemming/))\n* returned the result sorted by score, remember that the title has a weight of 1.0, and the plot a weight of 0.5. So when the word or related words are found in the title the score is larger.\n---\n\u003c/details\u003e\n\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003e\n    Find all the movies with a title that contains the word 'heat' or related to 'heat'\n  \u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\nIn this case you have to set the criteria to a the field title using the `@title` notation.\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@title:heat\" RETURN 2 title plot\n1) (integer) 2\n2) \"movie:1141\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"plot\"\n   4) \"A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist.\"\n4) \"movie:818\"\n5) 1) \"title\"\n   2) \"California Heat\"\n   3) \"plot\"\n   4) \"A lifeguard bets he can be true to just one woman.\"\n\n```\n\nSo only 2 movies are returned.\n\n---\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003e\n  Find all the movies where the title contains 'heat' and does NOT contains 'california'\n  \u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\nFor this you add parentheses around the field condition and add the `-` sign to 'california'.\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@title:(heat -california)\" RETURN 2 title plot\n1) (integer) 1\n2) \"movie:1141\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"plot\"\n   4) \"A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist.\"\n\n```\n\nOnly one movie is returned.\n\nIf you do not put the `( .. )` the `-california` condition will be applied to all the text fields.\n\nYou can do test this with the following queries:\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@title:(heat -woman)\" RETURN 2 title plot\n```\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@title:heat -woman\" RETURN 2 title plot\n```\n\nAs you can see the first query only searches for woman in the title and returns two movies \"Heat\" and \"California Heat\", where the second query eliminates \"California Heat\" from the list since the plot contains the word `woman`.\n\n---\n\u003c/details\u003e\n\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003e\n  Find all the 'Drama' movies that have 'heat' in the title\n  \u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\nAs you have seen earlier the movie index contains:\n* the `title` and plot as TEXT\n* the `genre` as TAG.\n\nYou saw earlier how to place a condition on a TEXT field.\n\nThe [TAG](https://oss.redislabs.com/redisearch/Tags/) is a little bit different as the index engine does not do any stemming.\n\nTo set a condition on this field you must use the `@field:{value}` notation, the `{...}` indicates that it is a TAG condition\n\n\n```\n\u003e  FT.SEARCH \"idx:movie\" \"@title:(heat) @genre:{Drama} \" RETURN 3 title plot genre\n1) (integer) 1\n2) \"movie:1141\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"plot\"\n   4) \"A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist.\"\n   5) \"genre\"\n   6) \"Drama\"\n```\n\nAs you can see this query applies conditions to two different fields with an exact match on the TAG.\n\nTAG is the structure to use when you want to do exact matches on strings/words.\n---\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003e\n  Find all the 'Drama' or 'Comedy' movies that have 'heat' in the title\n  \u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\nThis is similar to the previous query, you can pass a list of values with the `|` to represent the OR.\n\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@title:(heat)  @genre:{Drama|Comedy} \" RETURN 3 title plot genre\n\n1) (integer) 2\n2) \"movie:1141\"\n3) 1) \"title\"\n   2) \"Heat\"\n   3) \"plot\"\n   4) \"A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist.\"\n   5) \"genre\"\n   6) \"Drama\"\n4) \"movie:818\"\n5) 1) \"title\"\n   2) \"California Heat\"\n   3) \"plot\"\n   4) \"A lifeguard bets he can be true to just one woman.\"\n   5) \"genre\"\n   6) \"Comedy\"\n```\n\n\nYou can also put the '|' between all the conditions to search for example all movies that have \"heat\" in the title, or that are Comedy or that are Drama. The query will look like:\n\n```\nFT.SEARCH \"idx:movie\" \"@title:(heat) | @genre:{Drama|Comedy} \" RETURN 3 title plot genre\n```\n\n---\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003eFind all 'Mystery' OR 'Thriller' movies, released in 2014 OR 2018\u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\nIn this query, the new item is the query on a numeric field (release_year).\n\nLike before, for the condition you have to use the `@field:` notation, but for a numeric field you have to put the interval of the condition.\n\nIn this query it will be two conditions with an OR (`|`).\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@genre:{Mystery|Thriller} (@release_year:[2018 2018] | @release_year:[2014 2014] )\"   RETURN 3 title release_year genre\n\n1) (integer) 3\n2) \"movie:461\"\n3) 1) \"title\"\n   2) \"The Boat ()\"\n   3) \"release_year\"\n   4) \"2018\"\n   5) \"genre\"\n   6) \"Mystery\"\n4) \"movie:65\"\n5) 1) \"title\"\n   2) \"The Loft\"\n   3) \"release_year\"\n   4) \"2014\"\n   5) \"genre\"\n   6) \"Mystery\"\n6) \"movie:989\"\n7) 1) \"title\"\n   2) \"Los Angeles Overnight\"\n   3) \"release_year\"\n   4) \"2018\"\n   5) \"genre\"\n   6) \"Thriller\"\n```\n\n\n---\n\u003c/details\u003e\n\nSummary\n\n* Fieldless queries apply to all TEXT fields and use the words and their base form (stemming)\n* To apply a condition to a specific field you must use the `@field:` notation\n* Multiple conditions are \"intersection\" (AND condition), to do a \"union\" (OR condition), you have to use the \"`|`\" character.\n\n----\n### Sort\n\nA very common use case when querying data is to sort the data on a specific field, and paginate over the result.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003eQuery all the `Action` movies, sorted by release year from most recent to the oldest\u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@genre:{Action}\"  SORTBY release_year DESC RETURN 2 title release_year\n 1) (integer) 186\n 2) \"movie:360\"\n 3) 1) \"release_year\"\n    2) \"2019\"\n    3) \"title\"\n    4) \"Spider-Man: Far from Home\"\n ...\n20) \"movie:278\"\n21) 1) \"release_year\"\n    2) \"2016\"\n    3) \"title\"\n    4) \"Mechanic: Resurrection\"\n```\n\nThe first line contains the number of documents (`186`) that match the query condition.\n\nThe FT.SEARCH command, by default, returns the first ten documents. You will see in the next query how to paginate.\n\nYou can only use one SORTBY clause in an FT.SEARCH query, if you want to sort on multiple fields, for example sorting movies by `genre` ascending and `release_year` descending, you have to use an FT.AGGREGATE, this is covered in the [next section](008-aggregation.md).\n\nNote: The field used in the [SORTBY](https://oss.redislabs.com/redisearch/Sorting/#specifying_sortby) should be part of the index schema and defined as SORTABLE.\n---\n\u003c/details\u003e\n\n----\n### Paginate\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003eQuery all the `Action` movies, sorted by release year from the oldest to the most recent one, returning the record by batch of 100 movies\u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@genre:{Action}\" LIMIT 0 100  SORTBY release_year ASC RETURN 2 title release_year\n  1) (integer) 186\n  2) \"movie:892\"\n  3) 1) \"release_year\"\n     2) \"1966\"\n     3) \"title\"\n     4) \"Texas,Adios\"\n...\n200) \"movie:12\"\n201) 1) \"release_year\"\n     2) \"2014\"\n     3) \"title\"\n     4) \"Fury\"\n```\n\nThe result is very similar to the previous query:\n* 186 documents found\n* the first document is the oldest one, released in 1966\n* the latest movie of the batch was released in 2014\n\n\nTo paginate to the next batch you need to change the limit as follows:\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@genre:{Action}\" LIMIT 100 200  SORTBY release_year ASC RETURN 2 title release_year\n```\n---\n\u003c/details\u003e\n\n\n----\n### Count\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003eCount the number of 'Action' movies\u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\nBased on the sample queries that you have seen earlier, if you specify `LIMIT 0 0` it will give you the number of documents based on the query condition.\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@genre:{Action}\" LIMIT 0 0\n\n1) (integer) 186\n```\n---\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n  \u003ci\u003e\u003cb\u003eCount the number of 'Action' movies released in 2017 \u003c/b\u003e\u003c/i\u003e\n  \u003c/summary\u003e\n\nBased on the sample queries that you have seen earlier, if you specify `LIMIT 0 0` it will give you the number of documents based on the query condition.\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@genre:{Action}\" FILTER release_year 2017 2017 LIMIT 0 0\n\n1) (integer) 5\n```\n\nYou can also use the following syntax:\n\n```\n\u003e FT.SEARCH \"idx:movie\" \"@genre:{Action} @release_year:[2017 2017]\" LIMIT 0 0\n\n1) (integer) 5\n```\n\n---\n\u003c/details\u003e\n\n\n----\n\n## How to run it locally?\n\n### Running the application in Docker\n\nThe application and all the services, including Redis Search, are available as a Docker Compose application.\n\n**NOTE: You need to specify required environment variables in ```docker-compose.yml``` under service ```rest-java```**:\n\n```\nREDIS_ENDPOINT_URL=redis://\u003cyour endpoint url\u003e\nREDIS_PASSWORD=\nREDIS_INDEX=(by default idx:movie)\n```\n\nTo run the application:\n\n```\n\u003e docker-compose up --force-recreate --build\n```\n\nThis Docker Compose will start:\n\n1.Redis Searchinstance on port 6380, and import all movies, actors and create indexes\n1. The Java REST Service available on port 8085\n1. The frontend on port 8084\n\nOnce started you can access the application and its services using the following URLs:\n\n* http://localhost:8084\n* http://localhost:8085/api/1.0/movies/search?q=star\u0026offset=0\u0026limit=10\n\n\n\n#### Stop and Delete Everything\n\nRun the following command to delete the containers \u0026 images:\n\n```\n\u003e docker-compose down -v --rmi local --remove-orphans\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis-developer%2Fdemo-movie-app-redisearch-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredis-developer%2Fdemo-movie-app-redisearch-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis-developer%2Fdemo-movie-app-redisearch-java/lists"}