Full text search with Firestore & Meili search API's
Tags: javascript, firebase, react, backend
Published: 2023-11-06 11:16:25

In this post, we will focus on the APIs provided by Meilisearch which we can use to add our data to their full text search platform.

Ok lets dive into this post where we will focus about understanding Meilisearch's APIs

We will be discussing the implementations only in Javascript. If you want to use other languages, Meilisearch has a good documentation on them as well. In this post I will be explaining the JavaScript examples in a detailed manner.

I am assuming you have created a Express JS project with Node  JS Google Cloud Functions for this post.

So in order to use Meilisearch inside our application, we need to install their library. So run the following command inside your project.

```jsx

npm i meilisearch

```

After installing the package, I will discuss the sequence of how you can add your data points into a Meili search instance.

1. Creating an index with a primary key (Unique id)
2. Adding the data points into the index.
3. Updating and deleting the data points.
4. Deleting the index.
5. Searching an index to get the values which we can show it in the frontend.

## Creating Index

First let's dive into the concept of creating an index in Meili search. As a software engineering principal, when a data point is inserted into a SQL table we need a unique id which would be a primary key in the sense of SQL. So If we have a list of 5 data points of famous Hollywood movies, we are going to consider "movieId" as a unique key or as the Primary key of these values we have. With this primary key we are going to create an index in our Meilisearch index. 

So first lets import Meilisearch at the top of the file and use it to connect to the host Meilisearch instance.


```jsx

const { MeiliSearch } = require("meilisearch");

const client = new MeiliSearch({
  host: "thehost.com",
  apiKey: "yourkey",
});

```

Now lets create an index called "movies" with "movieId" as primary key.

```jsx

 await client.createIndex("movies", { primaryKey: "movieId" });

```

Now let us add data points into the "movies" index. As I said before, the data points should have "movieId" key in them and it has to be unique. If its not unique, the code will return an error and the data wont be added.

```jsx
// sample data set

 const movies = [
    {
      movieId: '001',
      title: 'The Shawshank Redemption',
      description:
        'Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.',
      posterUrl:
        'https://res.cloudinary.com/dncqpakzo/image/upload/v1698677755/osbnnkayh6fxxublgd7x.jpg', // Placeholder URL
    },
    {
      movieId: '002',
      title: 'The Godfather',
      description:
        'The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son.',
      posterUrl:
        'https://res.cloudinary.com/dncqpakzo/image/upload/v1698677743/ehoraz6bpdf9h7w2wuji.jpg', // Placeholder URL
    },
    {
      movieId: '003',
      title: 'The Dark Knight',
      description:
        'When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.',
      posterUrl:
        'https://res.cloudinary.com/dncqpakzo/image/upload/v1698677752/dmhppb1mgsjsngnasbkj.jpg', // Placeholder URL
    },
    {
      movieId: '004',
      title: 'Inception',
      description:
        'A thief who enters the dreams of others to steal secrets from their subconscious is given the inverse task of planting an idea into the mind of a CEO.',
      posterUrl:      'https://res.cloudinary.com/dncqpakzo/image/upload/v1698677744/si9lqrszqihl8kn23aqq.jpg', // Placeholder URL
    },
    {
      movieId: '005',
      title: 'Forrest Gump',
      description:
        'The presidencies of Kennedy and Johnson, the Vietnam War, the Watergate scandal and other historical events unfold from the perspective of an Alabama man with an IQ of 75.',
      posterUrl:
        'https://res.cloudinary.com/dncqpakzo/image/upload/v1698677744/flvzglgv2mgbtvhkumbf.jpg', // Placeholder URL
    },
  ];

  const index = 'movies';

  await client.index(index).addDocuments([data]); 

```

Now if we want to delete the index, you can use the below code. Remember if you delete an index, all the data within the index will be deleted.

```jsx

 await client.deleteIndexIfExists('movies');

```


Same way if you want to delete a particular document, you can  use the below code.


```jsx

await client.index('movies').deleteDocument(movieId);

```

Now if you want to update a particular document, you can use the below code. Remember to have that particular 'movieId' inside the data object, so that it updates the correct value.

```jsx
const data = {
      movieId: '004',
      title: 'Inception',
      description:
        'A thief who enters the dreams of others to steal secrets from their subconscious is given the inverse task of planting an idea into the mind of a CEO by Leonardo Dicaprio',
      posterUrl:      'https://res.cloudinary.com/dncqpakzo/image/upload/v1698677744/si9lqrszqihl8kn23aqq.jpg', // Placeholder URL
    }

await client.index('movies').updateDocuments([data]);

```

Now comes the most important section where, we will be introducing the full text search function. We will be using the function provided by Meilisearch to retrieve the data points from the Meilisearch index

```jsx

const search = 'Leonardo'

const response = await client.index('movies').search(search, {limit: 7});

return response.hits

```

Thats it, we have discussed the important functions required to make our full text search work with Meilisearch. In the next post I will be discussing how we can integrate these functions in Google cloud functions with Express JS routes and implement all the functions above.  I will be making API routes and then calling the API routes to perform necessary actions like adding data points and performing search operations from the data we have uploaded.

I will also be using the above functions in cloud functions listeners where when you add a data point into Firestore via Web V9 SDK or in some other form, the data will be automatically grabbed and added to the Meili search instance.

Thats it, we have successfully made API routes to create an index, add, update, delete documents and a route where you can apply full text search.

We can use these code to apply full text search to any of our Frontend applications which we will be doing in our next posts. I will be creating a search interface in a React/Next JS website and in a React Native app.

You can view the complete code and see how the search interface works in a live demo below.

https://github.com/Gautham495/blog-code-snippets

https://demos.gauthamvijay.com/