How To Build A Movie Search App With React and ElasticSearch

Raj Meghpara
All things #search
Published in
11 min readJun 11, 2018

--

MovieSearch App: Built with ReactiveSearch and ❤ (link to the app)

We’ve updated this post for 2022 to use the latest React and ReactiveSearch versions, you can read it over here: https://blog.reactivesearch.io/react-search-ui-tutorial

In this post, we will use React and Elasticsearch to build a MovieSearch app. I know you like React, and watching movies, but what is this Elasticsearch thing I’m talking about. Don’t worry. This blog post will give you a kickstart into understanding the basics of Elasticsearch — What is it? Why should you care about it? And, how can you use it with React to build powerful apps painlessly?

You should try out the Live Demo of our final app here to see what we will be building. I will wait for you!

.

.

.

.

.

What is Elasticsearch and why should you care about it?

Now, let’s understand the role of Elasticsearch in helping us build the above UI. Elasticsearch is a super-fast, open-source, full-text search engine. It allows you to store, search, and analyze big volumes of data quickly (we are talking milliseconds here). It is generally used as the underlying engine/technology that powers applications that have complex search features and requirements. You can read more about it here.

With Elasticsearch, you can build a fast search utilizing its powerful Query DSL. However, setting up Elasticsearch correctly requires a lot of work. For instance, the data mapping, analyzers and tokenizers need to be set correctly or you may not receive accurate search results back. Besides, the more filters that get applied along with the search query, the more complex the resulting search query becomes.

We, at Appbase, have built some open-source tools to help you do all these things with the matter of some clicks.

  • A tool to add data into Elasticsearch — Importer
  • A tool to view Elasticsearch data like an excel sheet — Data Browser
  • A tool to generate relevant Elasticsearch queries easily — Query Builder
  • A tool to build UI components with an Elasticsearch backend — Reactive Search (we will be using this to build our MovieSearch app’s UI).

In this blog post, with the help of some of these toolings, we will utilize the strengths of Elasticsearch with React to build powerful apps.

How to use Elasticsearch with React?

We will be using ReactiveSearch open-source library to build the MovieSearch app in this post. It offers a range of highly customizable rich UI components that can connect with any Elasticsearch server and provide you with a good default queries for all generic use-cases (think E-commerce, Aggregators, Events et al) bundled into these components. ReactiveSearch will help us to build UI widgets for filters and search-related UI elements.

Image: A sneak peek into the UI components offered by ReactiveSearch.

In the second part of the tutorial, I will show how to use Server Side Rendering (aka SSR) with Next.js to instantly load our Movie Search UI and also get some sweet SEO benefits.

You can try out the SSR enabled Live Demo here.

Things we will need

In order to build MovieSearch app, we will need a set of things before we can get started with writing the actual code —

Dataset for MovieSearch App
To make a great UI we should have a good dataset. We found an awesome dataset for our MovieSearch App. Here is the link to the dataset: https://www.kaggle.com/rounakbanik/the-movies-dataset.

Elasticsearch Hosting
You can set up and install an Elasticsearch server by following the official installation guide, or you can create a free account at appbase.io which provides Elasticsearch hosting as a service and is easy to use. For simplicity, we will be using appbase.io service to get started with.

I’ve already created an appbase app with the MovieSearch dataset indexed in it. You can browse it with dejavu over here:

The URL of the above app is:

app="movie_app_final"
url="https://7fdc8bd59c19:7b573cb7-5bb1-491a-b298-a03ad86970c9@arc-cluster-appbase-demo-6pjy6z.searchbase.io"

Now, we will go step-by-step and build our application. We’ll use Codesandbox.io to generate code at each intermediate step, making it easy to test. Click on the above link and click on Open React button.

Step 1: Base setup for CRA with ReactiveSearch

If you have tried out the Create React App before, you will feel right at home as we build this app.

Create React App

Initialize the CRA setup. We will use npm as the package manager, you can also use yarn instead.

npx create-react-app moviesearch
cd moviesearch
npm start

Note: npx comes with npm 5.2+ and higher, see instructions for an older release here.

One of the great benefits of using CRA is that it works without requiring to set up a build configuration.

At this point, you should have a directory structure similar to this:

moviesearch
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── package-lock.json
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
└── App.css
└── App.js
└── App.test.js
└── index.css
└── index.js
└── logo.svg
└── registerServiceWorker.js

Install ReactiveSearch

Next, we will install ReactiveSearch.

npm install @appbaseio/reactivesearch

In addition to the code sandbox above, you can also try the code so far directly from our GitHub — https://github.com/appbaseio-apps/MovieSearch-app/tree/step1.

Step 2: Setup with DataSearch and all the filter components from ReactiveSearch

Adding the first ReactiveSearch component: ReactiveBase

All the ReactiveSearch components are wrapped inside a container component — ReactiveBase which glues the Elasticsearch index and the ReactiveSearch components together. We’ll use this in /src/App.js:

The app and url are taken from my appbase.io app. You can create your own app and add those from your dashboard.

We can set our app’s theme by providing theme attribute prop to our ReactiveBase component. Here, we will use this to give our app a night mode look:

Now let’s start the server with npm start.

Breaking Down The MovieSearch App

To add any component, we have to first import it from the ReactiveSearch library using this statement:

import { component-name } from '@appbaseio/reactivesearch';

Component #1: DataSearch

DataSearch component creates a search bar UI which allows us to search for movies.

Search bar (Using DataSearch Component)

In this component, we are passing the dataField prop with original_title.search value. Here,original_title is the name of the field in the app on which we want to apply our search.

queryFormat sets the query’s format. It can have values of or or and. or returns all the results matching any of the search query text’s parameters. For example, searching for “bat man” with or will return all the results matching either “bat” or “man”. On the other hand with and, only results matching both “bat” and “man” will be returned. It returns the results matching all of the search query text’s parameters.

You can learn more about this component over here.

Component #2: MultiList

We will create a genre-based filterable UI component using MultiList.

Genre Filter (using MultiList component)

In this component, we are passing genres_data as the dataField, the .raw suffix signifies that we are using the Keyword type (over the Text type) which is suitable for performing an aggregation. Another interesting prop here is react. It specifies the components to watch for when updating the current MultiList’s data view. For example: If we search for “Bat man”, the MultiList’s view will also be simultaneously updated to only show results that match the search query. The showCount prop controls whether to show the count values next to each item. The innerClass prop allows us to set CSS styles to particular elements within the component. You can learn more about this component here.

Component #3: SingleRange

We will use the SingleRange component to create a revenue filter UI widget.

Revenue Filter( Using SingleRange Component)

Here, we are passing the data parameter, in which we will give different options with start and end values for revenue. Other parameters are self-explanatory. You can learn more about this component here.

Component #4: RangeSlider

RangeSlider will help us to make a UI widget for a ratings based filter.

Rating Filter( Using RangeSlider Component)

Here, we are passing range prop as an object with start and end keys. You can learn more about it here.

Component#5: MultiDataList

MultiDataList will help us make a UI a language-based filter.

Language Filter(Using MultiDataList Component)

In contrast to MultiList, we also pass a data prop to MultiDataList which is used for displaying the filter options. You can learn more about MultiDataList over here.

Component#6: DateRange

We will use the DateRange component to create a filter for movie release dates.

Release Date Filter (using DateRange Component)

In DateRange, we will just be passing the obvious props. It goes without saying that the dataField prop for DateRange expects a field of Date type. You can learn more about DateRange component over here.

In addition to the above code sandbox, you can also try the code so far directly from our GitHub repo — https://github.com/appbaseio-apps/MovieSearch-app/tree/step2.

Step 3: Styling the components we have so far

Now that we have added all the filter components with DataSearch component, it’s time to style them!

We are using the majority of styling for setting the layout. We will use flex to design our layout. We will create a leftbar div, which will contain all of our filter components. Also, we have added styles for the top navigation bar, which contains the DataSearch component. We have used innerClass property of each component to style the inner parts of it.

You can copy the CSS styles from here and add them to App.css and import it in your App.js with a import './App.css' statement along with our other imports. That’s all!

In addition to the code sandbox above, you can also try the code so far directly from our GitHub repo — https://github.com/appbaseio-apps/MovieSearch-app/tree/step3.

Step 4: Adding ReactiveList component and making our app responsive

Component#7: ReactiveList

And finally, we will use the ReactiveList component to show the movies that match our search and filters in a fancy card-based view.

Movie cards (using ReactiveList component)

The pagination and paginationAt props determine whether we will use pagination (or an infinite scroll) to display our results and when using pagination, where the position of the pagination component would be at. We have set it to bottom. You can also try passing top or both.

The resultStats prop which will show the number of movies in the result and other statistical information of result. sortOptions will provide options to sort results by their popularity, alphabetic order and ratings. You can also add more sort options depending on your data. You can learn more about the ReactiveList component over here.

Next, we will make our app responsive so that it looks good in any size of the screen. We will use a toggle button for smaller screens so that the user can switch between the results view of movies and the filters view. Here, I have used a state variable isClicked to decide which view should be displayed.

In addition to the code sandbox above, you can also try the code so far directly from our GitHub —https://github.com/appbaseio-apps/MovieSearch-app/tree/step4.

Step 5: Adding overlay effect on result cards

Now in the final step, we will add a fancy overlay effect on result cards so that users can view the movie information by hovering over them.

Image: Showing the overlay effect on result cards in action

In addition to the code sandbox above, you can also try the code so far directly from our GitHub —https://github.com/appbaseio-apps/MovieSearch-app/tree/step5.

If you have been running the setup locally, you can open the app in the browser after applying the above changes:

npm start
# open http://localhost:3000

You should see the app running. Now search for your favourite movies and enjoy!

Woohoo!!! We made it! We have made a beautiful MovieSearch App! We went from a boilerplate with CRA to creating a MovieSearch UI, hopefully well within an hour.

Bonus Step: Using SSR with next.js

If you have come this far, ReactiveSearch also allows performing server-side rendering (aka SSR). We will use the next.js library to showcase this!

You can read the following article about the history of SSR with ReactiveSearch and how it enables you to build a blazing fast search UI besides giving some sweet SEO benefits.

As a first step, install next.js in your project:

npm install --save next

Make sure you add a script to your package.json like this:

{
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}

Usage

First, import initReactivesearch:

import initReactivesearch from '@appbaseio/reactivesearch/lib/server';

Then, evaluate the initial state:

const initialState = await initReactivesearch(...);

and finally, pass the computed initial state to ReactiveBase component.

<ReactiveBase {...props} initialState={initialState}>
...
</ReactiveBase>

If you got stuck somewhere, you can check out the details about SSR with ReactiveSearch over here. Now, create a directory named pages in your root directory and move all the JS files in it. Create another directory named static in the root directory to store our app’s logo and other image files we have used. Change _document.js file as it is mentioned in the above link.

And we are done! Just run this command:

npm run dev

And you will see the MovieSearch app with fast rendering at http://localhost:3000. Try to refresh the page to see the effect of next.js.

In case you are missing a step, you can get the code so far by following these:

git clone https://github.com/appbaseio-apps/MovieSearch.git
cd moviesearch
npm install
npm run dev
# open http://localhost:3000

Summary

Here comes the end of our journey and we have got our awesome MovieSearch app built with ReactiveSearch. To summarize our journey:

This post introduces Elasticsearch and ReactiveSearch — A UI components library written in React for building search UIs. We jump through the hoops in a step-by-step manner to build our app.

  • Step 1: Base setup of CRA with ReactiveSearch (Codesandbox link: step1)
  • Step 2: Setup with DataSearch and all the filter components from ReactiveSearch (Codesandbox link: step2)
  • Step 3: Styling the components we have so far (Codesandbox link: step3)
  • Step 4: Adding ResultCard component and making our app responsive (Codesandbox link: step4)
  • Step 5: Adding overlay effect on result-cards (Codesandbox link: step5)

Using about 8 components, we were able to build a nice looking MovieSearch UI!

In the bonus step, we add SSR using next.js to enable a faster first paint (almost instantaneous) along with getting some sweet SEO benefits when running the app in a production setting.

Useful References

All ReactiveSearch components can be interactively tried using the playground https://opensource.appbase.io/playground/.

The documentation for all the above plus 20 other components is available at https://docs.appbase.io/ .

You can look at the code for this app at https://github.com/appbaseio-apps/MovieSearch

Finally, go ★ the project on Github so you can find it when you need to build that awesome search!

--

--