# Fine-tuning search results

Meilisearch is designed to offer a great search experience out of the box, but sometimes you need to customize it to better fit your needs. You can alter the search behavior for each index using the settings object.

For this chapter, we will be using a collection of movies as our dataset.

To follow along, first click this link to download the file: movies.json. Then, move it into your working directory and run the following command:

curl \
  -X POST 'http://localhost:7700/indexes/movies/documents' \
  -H 'Content-Type: application/json' \
  --data-binary @movies.json

# Ranking rules

Meilisearch sorts search responses based on an array of rules called rankingRules, which is part of the settings object.

The order of the rankingRules array matters: the first rule has the most impact and the last rule has the least. This is the default order:

"rankingRules": [
  "words",
  "typo",
  "proximity",
  "attribute",
  "sort",
  "exactness"
]

You can read more about each ranking rule and what it does in our dedicated guide.

In this example, we change the order of the ranking rules for the movies index by moving exactness to the top:

curl \
  -X PUT 'http://localhost:7700/indexes/movies/settings/ranking-rules' \
  -H 'Content-Type: application/json' \
  --data-binary '[
    "exactness",
    "words",
    "typo",
    "proximity",
    "attribute",
    "sort",
    "release_date:asc",
    "rank:desc"
  ]'

You can read more about ranking rules in our dedicated guide.

# Displayed attributes

By default, all attributes are displayed in search results but the displayedAttributes array in the settings object allows you to change that.

If you only want to display the title, poster, and overview for the movies index:

curl \
  -X PUT 'http://localhost:7700/indexes/movies/settings/displayed-attributes' \
  -H 'Content-Type: application/json' \
  --data-binary '[
    "title",
    "overview",
    "poster"
  ]'

You can read more about displayed attributes in our dedicated guide.

# Distinct attribute

If you have groups of almost identical documents, you may wish to only return one of them per search. distinctAttribute is a tool in the settings object that allows you to do just that.

When you set one of your attributes as the distinctAttribute, Meilisearch will not return more than one document with the same value associated to that attribute.

Suppose you have an e-commerce dataset with an index on jackets. There are several identical items with minor variations in color.

[
  {
    "id": 1,
    "description": "Leather jacket",
    "brand": "Lee jeans",
    "color": "brown",
    "product_id": "123456"
  },
  {
    "id": 2,
    "description": "Leather jacket",
    "brand": "Lee jeans",
    "color": "black",
    "product_id": "123456"
  },
  {
    "id": 3,
    "description": "Leather jacket",
    "brand": "Lee jeans",
    "color": "blue",
    "product_id": "123456"
  }
]

If you searched for lee leather jacket with the default settings, you would get all three documents. But if you set product_id as the distinctAttribute, Meilisearch will only return one of those jackets.

You can read more about the distinct attribute in our dedicated guide.

# Searchable attributes

Documents in Meilisearch are composed of multiple fields. By default, Meilisearch looks for matches in every field, but the searchableAttributes array in the settings object allows you to change that.

For example, if you search the movies index for 2012, Meilisearch searches for 2012 in every field: the title, overview, release_year, and so on. If you just want to search in the title field:

curl \
  -X PUT 'http://localhost:7700/indexes/movies/settings/searchable-attributes' \
  -H 'Content-Type: application/json' \
  --data-binary '["title"]'

Meilisearch will now only consider title during search, and you will see fewer results.

NOTE

Meilisearch will still highlight matches in other fields, but they won’t be used to compute results.

# The order of searchableAttributes

The order of the searchableAttributes array corresponds to the order of importance of the attributes.

  [
    "overview",
    "title",
  ]

With the above order, matching words found in the overview field will have a higher impact on relevancy than the same words found in title. You can read more about this in our relevancy guide.

# Stop words

Meilisearch allows you to ignore certain words in your search queries by adding them to the stopWords array. A good example is the word the in English.

curl \
  -X PUT 'http://localhost:7700/indexes/movies/settings/stop-words' \
  -H 'Content-Type: application/json' \
  --data-binary '["the"]'

If you search for the cat after running the above command, Meilisearch will consider your search query to be cat, improving the speed and relevancy of your search.

You can read more about stop words in the API reference.

# Synonyms

The synonyms array lets you associate certain words in your dataset, telling Meilisearch that they are equivalent and interchangeable.

curl \
  -X PUT 'http://localhost:7700/indexes/movies/settings/synonyms' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "winnie": ["piglet"], 
    "piglet": ["winnie"]
  }'

This will set winnie and piglet as synonyms. Searching for either won't always return the same results due to factors like typos and splitting the query.

You can read more about it in our dedicated guide.

# Typo tolerance

Meilisearch is typo tolerant by default. It will help you find relevant search results even if you make spelling mistakes or typos, e.g., searching for swaj instead of swan.

The typoTolerance object allows you to:

  • Enable or disable the typo tolerance feature
  • Configure the minimum word size for typos
  • Disable typos on specific words
  • Disable typos on specific attributes

Meilisearch accepts one typo for query terms containing 5 or more characters by default. If you search the movies index for swaj, you will not get any results.

curl \
  -X PATCH 'http://localhost:7700/indexes/movies/settings/typo-tolerance' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "minWordSizeForTypos": { "oneTypo": 4 }
}'

The above code sample sets the minimum word size for one typo to 4 characters. If you search for swaj now, you should get some results.

You can read more about typo tolerance in our dedicated guide.

# Faceting

Meilisearch allows you to create faceted search interfaces, refining search results based on broad categories called facets. Like filters, you need to add the attributes you want to use as facets to filterableAttributes.

When creating a faceted search interface, it is helpful to display how results are distributed between the different categories. For example, a user might want to know how many of their results have a genre of comedy and how many have a genre of horror. Meilisearch supports this with the facets search parameter.

Using the faceting settings, you can configure the maximum number of facet values returned for each facet.

Suppose your results contain the following values for the genres facet: Action, Adventure, Science Fiction, and Comedy. After running the below code sample, you would only see how results are distributed between the Action and Adventure genres.

curl \
  -X PATCH 'http://localhost:7700/indexes/movies/settings/faceting' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "maxValuesPerFacet": 2
  }'

You can read more about faceting in our dedicated guide.

# Pagination

By default, Meilisearch returns 1000 results per search. This limit protects your database from malicious scraping.

The code sample below sets this limit to 500:

curl \
  -X PATCH 'http://localhost:7700/indexes/movies/settings/pagination' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "maxTotalHits": 500
  }'

Now, users won't be able to access search results beyond 500.

You can read more about pagination in our dedicated guide.

The next chapter tackles more advanced topics, including security and data backup.