Meilisearch 1.10

Today we're announcing Meilisearch v1.10. In this article, we’ll review the most impactful changes. For an exhaustive listing, check out the changelog on GitHub.

🚀
Meilisearch 1.10 is available on Meilisearch Cloud, too—upgrade now!

We’re excited to announce that federated search is finally coming to Meilisearch. This feature extends the multi-search API to allow you to merge results from multiple queries into a single, unified response. You can now search different indexes and get the most relevant results across the entire dataset, not only the most relevant for each index.

For SaaS platforms that need to search across various types of resources or ecommerce sites with diverse product categories, federated search is a game-changer.

Here is an example payload for making a federated search request against the movies and comics indexes:

{
  "federation": {
    "offset": 5,
    "limit": 10
  },
  "queries": [
    {
      "q": "Batman",
      "indexUid": "movies"
    },
    {
      "q": "Batman",
      "indexUid": "comics"
    }
  ]
}

In this example, the federated search response will look like this:

{
  "hits": [
    {
      "id": 42,
      "title": "Batman returns",
      "overview": "..",
      "_federation": {
        "indexUid": "movies",
        "queriesPosition": 0
      }
    },
    {
      "comicsId": "batman-killing-joke",
      "description": "..",
      "title": "Batman: the killing joke",
      "_federation": {
        "indexUid": "comics",
        "queriesPosition": 1
      }
    },
 ],
  "processingTimeMs": 0,
  "limit": 2,
  "offset": 0,
  "estimatedTotalHits": 2,
  "semanticHitCount": 0
}

Query weighting

Federated search isn't just about combining results; it's about making those results more meaningful and relevant. Thanks to query weighting, you can prioritize certain queries over others, ensuring that the most important data rises to the top.

The example payload below uses query weighting in a federated search to give more importance to documents where the boosted field is true:

{
  "federation": {},
  "queries": [
    {
      "q": "iphone case",
      "indexUid": "products",
      "filter": "BOOSTED = true",
      "federationOptions": {
        "weight": 3.0
      }
    },
    {
      "q": "iphone case",
      "indexUid": "products"
      // federationOptions.weight defaults to 1
    }
  ]
}

New: language settings for queries and documents

By default, Meilisearch automatically detects the language used in documents and queries. This comes with some limitations for edge cases. Meilisearch 1.10 introduces new language settings that allow users to manually customize their language preferences.

There are two ways to state the language used in a search:

  • Set the language used in a query
  • Set the language used in a document field

Setting the search query locale

You can define which language is used in a query in the search parameters.

Example payload for searching with query locales:

{
   "q": "進撃の巨人",
   "locales": ["jpn"]
}

Setting the document attributes’ locales

You can define which language is used in your dataset via the index settings.

Example payload for settings with localizedAttributes:

{
  "localizedAttributes": [
    {
      "locales": ["jpn"], 
      "attributePatterns": ["*_japanese"]
    }
  ]
}
💡
Meilisearch support all ISO-639-2B locales.

Self-hosting: Ubuntu v20 is now required

If you’re self-hosting Meilisearch, take note: Meilisearch 1.10 now requires Ubuntu version 20. This update ensures compatibility with the latest features and maintains optimal performance and security. We advise reading the documentation on how to upgrade your Ubuntu release.

💡
This change does not affect Meilisearch Cloud users.

Experimental: AI-powered search DX improvements

New: custom headers to REST API-based embedders

Meilisearch 1.10 supports sending custom headers to your API-based embedding service. When using the rest source for your embedder settings, Meilisearch now accepts an optional headers object. These headers will be added to all requests made to the embedder API.

Example payload for embedder settings:

{
  "source": "rest",
  "apiKey": "•••••••••••••••••",
  "headers": {
    "Custom-Header": "value"
  }
}

New: quality of life improvements

Additionally, we added some minor changes to make working with Meilisearch AI-powered search API easier:

  • Embedder settings now accept a url parameter for OpenAI embedder to access OpenAI through a proxy
  • Embedder settings now accept a dimensions parameter for ollama embedder
  • Meilisearch now includes _vectors in the response for documents without vectors (only when retrieveVectors is enabled)

⚠️ Breaking: REST API-based embedders breaking changes

The API for configuring an embedder based on a REST API (e.g., OpenAI, Mistral, etc.) has quickly evolved and to avoid confusion, we have decided to reorganize the parameters in dedicated request and response fields.

In practice, this change:

  • removes query , inputFieldinputTypepathToEmbeddings and embeddingObject fields
  • adds request and response fields

Take a look at the example below to learn how to migrate to the new syntax.

Before — With Meilisearch 1.9

{
   "source": "rest",
   "url": "https://localhost:10006",
   "query": {
     "model": "minillm",
   },
   "inputField": ["prompt"],
   "inputType": "text",
   "embeddingObject": ["embedding"]
}

After — Starting with Meilisearch 1.10

{
   "source": "rest",
   "url": "https://localhost:10006",
   "request": {
     "model": "minillm",
     "prompt": "{{text}}"
   },
   "response": {
     "embedding": "{{embedding}}"
   }
}

Upgrade procedure

This procedure is only necessary if you're using REST API-based embedder. To upgrade to Meilisearch 1.10, follow these steps:

  1. Remove embedders with source "rest"
  2. Update your Meilisearch Cloud project or self-hosted Meilisearch instance as usual

Experimental: CONTAINS filter operator

Meilisearch 1.10 introduces the CONTAINS operator. This is still in the experimental stage due to some performance issues we’re working to resolve. This new filter operator allows to check if a substring is included in a larger string.

Given the document { id: 1, name: "Keffir" }, you can use the filter as follows:

  • name CONTAINS kef — search will match the document
  • name CONTAINS clifford — search will not match the document
💡
Remember all filters used lowercase, normalized strings (all accents are removed).
💬
Share your feedback via this Github discussion.

Experimental: update documents with a function

Meilisearch 1.10 allows you to edit documents by executing a Rhai function. This allows you to update only a part of your dataset using filters. Additionally, using a function allows you to implement dynamic logic based on your documents’ data.

The following payload updates the title of all documents with id above 3000:

{
  "filter": "id > 3000",
  "function": "doc.title = `✨ ${doc.title.to_upper()} ✨`"
}

This also enables more complex use cases, like implementing a decaying ranking strategy. Depending on your needs, you might implement a function such as the following that will be run regularly by a Cron job.

{
  "context": { "now": 1715423249 },
  "function": "
    // `posted_at` and `now` are Unix Epoch timestamps in seconds
    // they must be converted to hours.
    let age_hours = (context.now - doc.posted_at) / 60 / 60;
    doc.ranking_score = doc.upvotes ** 0.8 / (age_hours + 2) ** 1.8;
  "
}
💬
Share your feedback via this Github discussion.

And that’s a wrap for v1.10! These release notes only highlights the most significant updates. For an exhaustive listing, read the changelog on Github.

Upgrade with ease using Meilisearch Cloud.


Contributors shout-out

This release wouldn’t be possible without Meilisearch and Charabia contributors @Karribalu@hanbings@junhochoi@JWSong@PeterDaveHello@LukasKalbertodt, and @phillitrOSU.

We also want to extend special thanks to our SDK maintainers working hard to make Meilisearch available across many languages and frameworks. We’re excited for @Sherlouk and @Ja7ad to join our open-source maintainers. 💪


Stay in the loop of everything Meilisearch by subscribing to our monthly newsletter. To learn more about Meilisearch's future and help shape it, take a look at our roadmap and participate in our Product Discussions.

For anything else, join our developers community on Discord.