Implement Search Functionality with ElasticSearch, Firebase & Flutter
Tags: Flutter, Cloud, Dart, Firebase, Elasticsearch

Implement Search Functionality with ElasticSearch, Firebase & Flutter

Modern applications often require search functionality especially when apps have more textual content which cannot be presented to user in a single screen. The motivation of this article mainly comes from implementing search feature when using Firestore. Firebase doesn’t support String.contains() queries which can search for substrings inside text. But,

We’re programmers, we solve problems.

Photo by Marten Newhall on Unsplash

What this article covers:

Setup ElasticSearch & Kibana locally Basics of ElasticSearch (indexes) Use SearchDelegates in Flutter with Elastic.

1. Setup ElasticSearch & Kibana Locally

You probably would have heard about ElasticSearch but what is Kibana? It’s just a visualization tool to easily work with your Elastic data. Let’s get to the steps now. First download the zip files for elastic and kibana and unzip it inside your desired folder.

UnzippedFolderView.dart

Now, let’s just verify that our elastic search works. Open command prompt and navigate to elasticsearch/bin folder. Type elasticsearch.bat and hit enter.

At first, it will take some time to setup everything. Once it is done hit your browser with http://localhost:9200/ address. You should see something like this —

Elasticsearch Working

Now that our elasticsearch is working, we can load kibana to visualize our data. Steps are same. Just navigate to unzipped kibana/bin folder and type kibana.bat in cmd. Then in your browser enter this address — http://localhost:5601/

Kibana Home Page

🎉 Congrats, you’ve setup elasticsearch successfully.

2. Basics of Elasticsearch

First things first, elasticsearch stores data in an index. You can imagine it as a document. An index can have multiple types as a value. e.g. A Computer index can have Desktop and Laptop as their types. We communicate with elasticsearch with http methods.

GET — Get search results from elastic POST & PUT — Create or update data DELETE — Delete index or specific data in index

It’s time to play with Kibana now.

Photo by Zachary Kadolph on Unsplash

Head over to kibana and navigate to DevTools under Management. You’ll see an editor with some predefined http methods. We’ll create an index named services with some data to practice elasticsearch.

First, create a new index services with PUT. The syntax is very simple. We first define the http method we want to use (PUT in this case) followed by the relevant endpoint on which we want to perform the operation. Type this line inside the editor to create the index and click the play button to execute the query. This will create services index.

PUT /services

2. Let’s add some data to this index to query later. We use POST method to add data. This will create a unique id for each of the doc.

POST /services/_doc

{

“search_query”: “car services”,

“service_name”: “Car Services”,

}

_doc is the type of data in the index. Anything inside {} will be stored as a key-value data. For simplicity, I’m only including the name of the service and a special field search_query (We will see the reason behind this later). You can modify the fields according to your need. Once done, hit run and execute the query. This will add the data with auto generated id. If you want to specify your own id for the doc, simply add it to the relative path after _doc/ like this.

POST /services/_doc/<your-id>

{

“search_query”: “car services”,

“service_name”: “Car Services”,

}

3. To get all the data, use GET method on /_search endpoint. Upon executing the below query you’ll see all your data inside _source attribute.

GET /services/_search

4. To delete a specific index or specific doc with id, you’d use DELETE method as below,

DELETE /test DELETE /test/_doc/<doc-id>

5. To search data with query, we again have to use GET method with /_search endpoint. It also takes a body in which we’ll send the query to match. Let’s take an example below for our services index.

elastic query to search services with “ca” in name

As you can see, it takes a nested query JSON. The default_field indicates that the query has to be performed on [this] field. That’s why we included search_query field so that we can search names using lowercase letters for better results. And when you get the results back, you can use service_name field to populate it in the UI.

The query is passed in the query field which is a simple RegEx in our case which matched every string that contains letters ca. Feel free to modify this query according to your needs. Once you execute this, elasticsearch will return all the matching data.