Refining facets by ID with InstantSearch

Carolina Ferreira

Carolina Ferreira

Developer Advocate @ Meilisearch

··6 min read

In this guide, we’ll delve into the concept of faceting in Meilisearch and how to use it to display facet names while filtering by IDs.

What is faceting?

Faceting is a technique used in search engines to classify search results into multiple categories or “facets”. These facets can be anything from categories, tags, price ranges, to even colors. This makes it easier for the user to navigate and filter through the results, providing a more refined and efficient search experience.

Why use the ID as a facet filter?

For most applications and users, filtering by facet names, such as the genre of movies, is often sufficient and intuitive. Facet names are human-readable and provide a clear idea of what the filter does. However, in some use cases, it is preferable to filter by ID for a couple of key reasons:

  • Less prone to errors: IDs are usually simpler and standardized, making them less susceptible to typos or inconsistencies that might be present in facet names.
  • Unique identifiers: In some databases, facet names might be repeated with slightly different characteristics, whereas IDs are always unique. This is especially useful in cases where you have items with similar or identical names but different properties.

By using IDs for filtering but displaying the corresponding facet names to the users, you can achieve the best of both worlds: efficiency and usability. This way, you are leveraging the strengths of both IDs and names, making your application robust and user-friendly.

The ID-to-name challenge

In Meilisearch, facets are a specialized use-case of filters. Essentially, you can use any attribute added to the filterableAttributes list as a facet. When you add a facet parameter to your search query, Meilisearch will return a [facetDistribution](https://www.meilisearch.com/docs/reference/api/search#facetdistribution) object. This object provides the number of matching documents distributed among the values of the given facet.

JSON

However, if the field you’ve added to the filterableAttributes list is an ID, the facetDistribution object will return these IDs.

JSON

While IDs are great for back-end operations, they are not necessarily user-friendly or meaningful on the front-end. This is why you might want to map these IDs back to their corresponding facet names when displaying them in your user interface.

ID-to-name mapping in the frontend

Suppose you have a dataset of movies following the structure below:

JSON

You want a faceted search based on the movies genres. So you add genres.id to the filterable attributes list. Of course, in the UI you want to display genres.name, so that the user will see “Crime” on the UI instead of “7”.

Let’s dive into how you can accomplish this with InstantSearch and instant-meilisearch.

Using InstantSearch and instant-meilisearch

InstantSearch is an open-source front-end library to build search UIs. Instant-meilisearch is the go-to search client for integrating InstantSearch with Meilisearch.

To use instant-meilisearch with InstantSearch, you need to:

1. Import the required modules, including instantMeiliSearch

JavaScript

2. Establish a Meilisearch client with your Meilisearch host and search API key

JavaScript

3. Set up instantsearch with your Meilisearch index name and the search client

JavaScript

In this guide, we’ll use InstantSearch’s refinementList widget to map IDs to user-friendly names.

This widget comes with an optional parameter called transformItems. This function receives the items (or facets) and allows you to transform them before they are displayed on the UI. It also includes the full results data in its parameters.

Each item – or facet – includes the following properties:

  • count: the number of occurrences of the facet in the result set
  • value: the value used for refining (in our case it would be genres.id)
  • label: the label to display
  • highlighted: the highlighted label. This value is displayed in the default template

As you can see highlighted is the label used by default in the refinementlList widget.

With this information, we can use the transformItems function to display the genres.name instead of genres.id.

JavaScript

With this configuration, you’ll efficiently map IDs to more user-friendly names, enhancing the search experience for your users.

The full code should look like this:

JavaScript

This example shows how to implement ID-to-name mapping with vanilla JavaScript, but you can achieve similar results with your preferred frontend framework. Checkout the respective documentation for React and Vue.

For more things Meilisearch, you can subscribe to our newsletter. You can learn more about our product by checking out the roadmap and participating in our product discussions.

For anything else, join our developers community on Discord.

Carolina Ferreira

Carolina Ferreira

Developer Advocate @ Meilisearch

Carolina joined Meilisearch in 2020 as a Developer Advocate. With a background in translation and teaching, she discovered programming by chance and quickly became passionate about it. She has worked in DevRel and tech support and is now transitioning into a Solution Engineer role, enjoying the diverse challenges along the way. Outside of work, she loves staying active, music, cinema, traveling, and exploring new cuisines—one of her favorite parts of any trip.

Related articles