MeiliSearch and Speedy Search Queries

It's better than making a standard database query. Really.

November 04, 2020

MeiliSearch

A few weeks ago I came across MeiliSearch - an open source search API.

At first I thought to myself, "Is there really a need for a dedicated platform or service just for searching things?" and it turns out the answer is yes. Because the performance benefits when using something like MeiliSearch are huge.

Honestly, when I first came across MeiliSearch, I was amazed at how fast it was - searching hundreds of documents/records/listings and getting results in milliseconds was something that made me feel like reconsidering every single implementation of a search I've done while I've been working as a developer.

Let's face it, if you're making a website with a search functionality the user who is using it wants their results to appear as quickly as possible. Google might not be as popular as it is today if you didn't get 704 million results for "cheese" in under a second.

And while MeiliSearch isn't necessarily designed to be an open source version of Google, something which you could perhaps see as an alternative is the predictive search results that appear as you type - giving you suggestions, making your experience faster.

And that's what it all comes down to. Users like speed. And the faster the experience the better. How long would you spend actually on Google searching for something, not just the websites it returns?

So - to show what MeiliSearch is capable of - and to give a bit of a use case example, I'm going to walk you through how you'd set up MeiliSearch which would be used as a search for location information.

What we're making

The idea is to return location information such as a longitude and latitude when searching for a city name.

In terms of data, OpenWeather has a list of cities and their coordinates available to download from their website.

Installing

MeiliSearch pretty much acts like a server or executable application - and installing it is very simple.

There are many ways you can install it including Homebrew and Docker, but another way of installing it is by using the command line by making a cURL request:

curl -L https://install.meilisearch.com | sh

This will work on Mac and Linux, but for Windows you can use the Linux shell to run the cURL command.

Once that's complete, you can run MeiliSearch by executing:

./meilisearch

MeiliSearch should now be running.

Configuration

MeiliSearch itself doesn't really have an interface or config file - Instead the way you manage MeiliSearch is through environment variables or commands, and you'd manage yor data through it's REST API.

Because of this, I highly suggest the use of the Postman Collection so you can easily find and access the API endpoint.

Creating an index

The first thing we need to do is to create an index, this could be compared to a table or collection if you are using other database tools.

curl \
  -X POST 'http://127.0.0.1:7700/indexes' \
  --data '{
    "uid" : "locations",
    "primaryKey": "id",
  }'

The uid will pretty much be the name of our index, while the primaryKey is used to ensure that we don't duplicate anything when uploading new documents. Because of this - the value here must be unique.

You can actually leave the primaryKey field empty, MeiliSearch will rather cleverly identify a primary key to use when you upload your first document. However the way MeiliSearch does this is by looking for a key with the text "id" - so it's worth setting it when you're creating the index if you have any key values with "id" in it.

Adding documents

Now that the index is setup, you can add documents to it. To do this, create a POST request to MeiliSearch passing through a JSON file of our data.

curl \
  -X POST 'http://127.0.0.1:7700/indexes/locations/documents' --data @locations.json

I ran into an issue with MeiliSearch and their maximum file upload limit of 10MB, the file I was trying to upload was just over 40MB.

The way of configuring MeiliSearch itself and not the indexes, documents etc. is by passing it through as an argument on the run command. In my case, I increased the limit to 50MB using the --http-payload-size-limit option.

./meilisearch --http-payload-size-limit=52428800

MeiliSearch will accept the upload pretty much instantly, but processing the file will run in the background - especially if it's a big file.

In my case, it took just under 90 seconds. Which I suppose is acceptable as it contained just over 209 thousand documents. Which is definitely faster than typing them in one by one.

And that's the setup done. Really. In about four commands... Or about five in my case with the file size limit...

Searching

Of course, probably the most important part of a searching API is the search, and MeiliSearch actually has a small demo UI for you to easily see your documents.

To access it, visit http://localhost:7700 in your browser. Once loaded it will show you all your documents.

MeiliSearch search UI

And in the center of top of the page, you'll see a search field.

And entering a string will blow your mind.

I've been playing around - entering in a few different locations I can think of. The slowest I got was 80ms. Searching 200 thousand documents. That's fast.

For clarification, The speed gets faster as you search, so at the start a search term could last 70ms, but towards the end it frequently gets to 1ms.

Integrating within applications

Of course, your users don't want to use another entire website to search for something, and you don't really want them to leave the page you're on. So integrating it with your app or website is pretty important.

And yes, you guessed it. REST API. Or... Several official SDKs and packages. They're pretty much both the same thing, it's just that one is more convenient.

Anywho, to search your documents, make a request to the search endpoint:

curl 'http://127.0.0.1:7700/indexes/locations/search' --data '{ "q": "[SEARCH TEXT]" }'

Replace [SEARCH TEXT] with your query, and be dazzled that you we're able to search for your home town or city in a matter of milliseconds.

So, does it stop there?

No. It really doesn't. It gets better.

By default, MeiliSearch will actually search all the field values. Meaning you can actually search for things like the ID or even the longitude and latitude in this case.

So not only is it searching for a specific string very quickly, it's doing it several times. Impressive right?

Of course, this isn't always totally useful. For example, I'd only like to search for the name of the location, not necessarily anything else.

MeiliSearch allows you to configure this by updating the index.

curl \
  -X POST 'http://localhost:7700/indexes/locations/settings/searchable-attributes' \
  --data '[
    "name"
  ]'

Other things

MeiliSearch does lots of other things out of the box, and I feel this post is getting long enough already - so here's a small round up of other things MeiliSearch is capable of.

  • Support for typos - Meaning if you misspell something, there is a good chance it will appear.
  • Synonyms - If you search for a word that means the same thing, it can show you results based on the word you searched by.
  • Filtering - Using a query language - you can filter the results MeiliSearch returns.
  • Response formatting - Highlighting the matching text in responses.
  • Ranking configuration - By default MeiliSearch searches for typos first (Every word is a typo when you're halfway through typing it!)

It also has support for way way more stuff. And it's honestly one of the best tools I've come across in a long time.

Wrapping up and some final thoughts

As I explained earlier, speed is really important when it comes to a good user experience. And by having a search functionality that is accurate, but also accounts for other little features like typo support and above all incredible speed makes it all the more reason to give your users that experience.

With MeiliSearch, it's really easy to give that experience - and it can only result in positive reactions to your app or service.

So I'd honestly really recommend MeiliSearch for any application that has a search. You don't have to rip up your existing Database, providing the content you want to display or use on the results and what to search by are included in MeiliSearch, you should be pretty much good to go.

And yes. I'm so impressed with it - it most definitely isn't a "do as I say not as I do" situation. There is a search on my website now. Running Meilisearch.