meilisearch/MeiliSearch
 Watch   
 Star   
 Fork   
6 days ago
MeiliSearch

v1.50.0 🐐

Meilisearch v1.50 revamps the Dynamic Search Rules, adds support for federated document fetch in sharded configurations, among other improvements

Breaking changes

This release introduces breaking changes for users using some experimental features

dynamicSearchRules experimental feature

Request type changes

  1. priority has been replaced with precedence, which better reflects the behavior (lower precedence means the rule is applied first)
  2. conditions has been modified from an array to an object with two fields: "query" of type QueryCondition and "time" of time TimeCondition
  3. New type QueryCondition that contains the fields isEmpty (as previously) and words instead of contains (same type)
  4. It is now possible to pass isEmpty: false with words in a QueryCondition. Passing isEmpty:true with words still results in a synchronous error.
  5. New type TimeCondition with fields start and end (unchanged semantics from previous type).
  6. When specifying the selector of an Action, it is now mandatory to specify an id. Previously, it was optional, but the action would never trigger.
  7. When listing rules with POST /dynamic-search-rules, filter.attributePatterns has been replaced with filter.query, an optional string that searches in rule description and conditions.query.words.
  8. When calling DELETE /dynamic-search-rules/{:ruleUid} or PATCH /dynamic-search-rules/{:ruleUid} in a sharded configuration, endpoint will not return a HTTP 400 error if called on a follower remote rather than on the leader.

Response changes

  1. PATCH /dynamic-search-rules/{:ruleUid} and DELETE /dynamic-search-rules/{:ruleUid} now register an asynchronous task..
  2. The response is modified to return the registered task instead of the modified dynamic search rule.
  3. HTTP 404 is no longer returned if the {:ruleUid} portion of the URL refers to a rule that doesn't exist. This is because rules are processed asynchronously, and is consistent with the behavior of DELETE /indexes/{:indexUid}/documents/{:docId} for {:docId}

network experimental feature

The default behavior for users using the network experimental feature with sharding configured (leader not null) will change on the following routes:

  • GET indexes/:uid/documents
  • GET indexes/:uid/documents/:document_id
  • POST indexes/:uid/documents/fetch

Meilisearch will now fetch the documents from all the shards and not only on the local machine when processing the request. To keep the same behavior as before, users will have to set useNetwork to false when making their request.

🌈 Improvements

Scaling up the Dynamic Search Rules

  • Dynamic search rules scale up to 75K rules without any impact on the search
  • The API of Dynamic Search Rules has been simplified
    • It is harder to send conditions that will result in the rules never activating
  • This also unlocks future improvements such as filter activation conditions for search rules

Additions

  • Add a new DELETE /dynamic-search-rule route that deletes all the DSRs
  • Add the concept of "DSR fuel" that determines how much energy is spent resolving DSR during a search. The fuel is initialized with some default variables that can be overridden using environment variables:
    • MEILI_EXPERIMENTAL_DSR_FUEL_MAX_COUNTED_WORDS: max number of words considered inside of a search query for the purpose of finding conditions.query.words constraints. Defaults to 10, max value is 255
    • MEILI_EXPERIMENTAL_DSR_FUEL_MAX_ACTIVE_RULES: max number of active rules whose actions are evaluated. Defaults to 1000, max value is 4294967295
    • MEILI_EXPERIMENTAL_DSR_FUEL_MAX_PIN_ACTIONS: max number of pin actions that are applied. Defaults to 100, max value is 4294967295
    • MEILI_EXPERIMENTAL_DSR_FUEL_WORD_FUEL: max number of constraint combinations that are evaluated for the purpose of finding conditions.query.words constraints. Defaults to 4096, max value is 4294967295

By @dureuill in https://github.com/meilisearch/meilisearch/pull/6484 and https://github.com/meilisearch/meilisearch/pull/6506

Behavior changes

  • The conditions.query.words behaves differently from query.contains: previously, a rule would match if its conditions query.contains would be substrings of q in the search query in the sense of str::contains. Now, a rule matches if all the words in conditions.query.words appear in q (after normalization). For q = hero super, query.contains = super hero would not match, whereas conditions.query.words = super hero does now match. This behavior is more in line with regular search, and allows improving performance.
  • Dynamic search rules are now replicated from the leader to its follower, when in a sharded configuration

Federated document fetch routes

GET indexes/:uid/documents, GET indexes/:uid/documents/:document_id and POST indexes/:uid/documents/fetch will now fetch the documents from all the shards in the configured network.

Moreover, a new useNetwork parameter is available to activate or deactivate the usage of the network.

By @ManyTheFish in https://github.com/meilisearch/meilisearch/pull/6495

Support partial wildcards when requesting facets

The facets parameter in search and federated search now supports more wildcards. Previously, only the single wildcard "*" was supported, requesting all filterable fields.

Now, patterns containing * are supported with the same matching rules as in filterableAttributes.attributePatterns and localizedAttributes.attributePatterns, such as dogs.*, which will add to the facet distribution all filterable fields that match the pattern (such as dogs.intel, dogs.kefir, etc.).

By @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6497

🦋 Fixes

Fix migration from v1.48 and earlier

Migration via --experimental-dumpless-upgrade would fail in some cases in v1.49, when trying to migrate synonyms that contained no words (empty synonyms, or containing only separator tokens such as &).

Such synonyms are now ignored during migration, avoiding the issue.

By @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6501

Fix filter memory consumption in some cases

In some conditions, the memory consumption of filters would increase quadratically with the length of the filter. This is now resolved for these cases.

By @ManyTheFish in https://github.com/meilisearch/meilisearch/pull/6509

No longer reject some correctly-escaped filters

Fix a bug where some filters containing escaped characters (such as \) would cause search requests to fail with invalid_search_filter

By @dureuill in https://github.com/meilisearch/meilisearch/pull/6499

More fault-tolerant S3 snapshots

Potentially fix an issue when sending a request to AWS S3 to create a new multipart upload, ensuring we resend the request if it fails.

By @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6494

🔩 Miscellaneous changes

Full Changelog: https://github.com/meilisearch/meilisearch/compare/v1.49.0...v1.50.0

20 days ago
MeiliSearch

v1.49.0 🪺

✨ Enhancement

  • Improve the synonyms storage by @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6466 We improve synonyms' performance by changing how we store and retrieve them during query processing. Users may have experienced performance issues when the number of synonyms in an index was high, resulting in a significant impact on search performance. The Meilisearch support team advised moving the settings and synonyms-as-keywords to the dedicated documents. This is no longer an issue; synonyms are loaded lazily, only when a word matches a synonym. You can see performance improvements of up to 13x, depending on the number of synonyms.

🔩 Miscellaneous

23 days ago
MeiliSearch

v1.48.3 🫎​

🪲 Bug fixes

  • Fix a rare S3 snapshots bug by @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6472

    We fixed a rare bug that could appear when using the S3 snapshot system. The bug is a race condition that occurs when we try to recycle internal buffers to reduce memory usage, which can cause an internal error and abort the snapshot upload.

  • Avoid remote search to return the same document twice by @ManyTheFish in https://github.com/meilisearch/meilisearch/pull/6473

    When using the remote federated search, Meilisearch was returning the same document twice from different machines. This was due to an internal filter that was not forwarded properly to the remote instances.

🔩 Miscellaneous

New Contributors

Thanks to @0xfandom, who made his first contribution in https://github.com/meilisearch/meilisearch/pull/6468 🎉

Full Changelog: https://github.com/meilisearch/meilisearch/compare/v1.48.2...v1.48.3

28 days ago
MeiliSearch
29 days ago
MeiliSearch
2026-06-23 00:11:37
MeiliSearch

v1.48.1 🫎

Revert #6432 due to a dumpless upgrade bug report.

Full Changelog: https://github.com/meilisearch/meilisearch/compare/v1.48.0...v1.48.1

2026-06-22 16:24:42
MeiliSearch

v1.48.0 🫎​

✨ Enhancement

[Experimental] Render 🫎​ template route

by @Mubelotix in https://github.com/meilisearch/meilisearch/pull/5765

Introduces a new POST /render-template route that can be used to render any template or fragment on any input and associated renderRoute experimental feature that gates access to the route.

This route can be used to test document templates and fragments before and after having configured an embedder.

A body payload for the route is of the form:

{
  "template": /* templateTarget object */,
  "input": /* inputTarget object or null */
}

where template describes the template or fragment to render, and input describes what to use to render the template.

Upon calling this route, Meilisearch responds with:

{
  "template": "{{doc.text}}",
  "rendered": "template text after rendering using the input"
}

where template contains the unrendered base text of the document template, or the unrendered base JSON object of a fragment, and rendered contains the result of rendering the template of the chosen input.

If input is null in the request, then rendered is null in the response, and the route can be used solely to retrieve a template or fragment from the settings of an index.

Before calling the route

The API of this route is subject to change, so before calling this route, please enable the renderRoute experimental feature:

PATCH /experimental-features --json '{"renderRoute": true}'

Examples

  1. Rendering a document from an index on a document template from an embedder of that index
request
// POST /render-template

{
  "template": {
    "kind": "documentTemplate",
    "indexUid": "movies",
    "embedder": "myMoviesEmbedder"
  },
  "input": {
    "kind": "indexDocument",
    "indexUid": "movies",
    "id": "2"
}
response
{
  "template": "A movie titled {{doc.title}} whose description starts with {{doc.overview|truncatewords:10}}",
  "rendered": "A movie titled Ariel whose description starts with Taisto Kasurinen is a Finnish coal miner whose father has..."
}
  1. Rendering an inline document on a fragment from an embedder of an index
request
// POST /render-template

{
  "template": { 
    "kind": "indexingFragment", 
    "indexUid": "dogs", 
    "embedder": "multi",
    "fragment": "captionedImage" 
  },
  "input": { 
    "kind": "inlineDocument", 
    "inline": { // pass your document inline as a JSON object
      "kind": "dog",
      "name": "iko",
      "breed": "jack russell",
      "mime": "image/png",
      "image": "/9j/4AAQSk..."
    } 
  }
}
response
{
  "template": {
    "content": [
      {
        "type": "text",
        "text": "A picture of a {{doc.kind}} of breed {{doc.breed}}"
      },
      {
        "type": "image_base64",
        "image_base64": "data:{{doc.mime}};base64,{{doc.image}}"
      }
    ]
  },
  "rendered": {
    "content": [
      {
        "type": "text",
        "text": "A picture of a dog of breed jack russell"
      },
      {
        "type": "image_base64",
        "image_base64": "data:image/png;base64,/9j/4AAQSk..."
      }
    ]
  }
}
  1. Rendering a search query on a search fragment from a multimodal embedder of an index
request
// POST /render-template
{
  "template": { 
    "kind": "searchFragment", 
    "indexUid": "testIndex", 
    "embedder": "testEmbedder",
    "fragment": "justBreed"
  },
  "input": {
    "kind": "inlineSearch",
    "inline": { // pass the search query inline
      "q": "unused",
      "media": {
        "name": "iko",
        "breed": "jack russell"
      },
      "filter": "ignored"
    }
  }
}
response
    {
      "template": "It's a {{ media.breed }}",
      "rendered": "It's a jack russell"
    }
  1. Rendering an inline document on the document template from the chat settings of an index
request
// POST /render-template

{
  "template": {
    "kind": "chatDocumentTemplate",
    "indexUid": "movies"
	// no embedder to specify since chat document template is global to index
  },
  "input": {
    "kind": "indexDocument",
    "indexUid": "movies",
    "id": "2"
}
response
{
  "template": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }}\n{% endif %}{% endfor %}",
  "rendered": "id: 2\ntitle: Ariel\noverview: Taisto Kasurinen is a Finnish coal miner whose father has just committed suicide and who is framed for a crime he did not commit. In jail, he starts to dream about leaving the country and starting a new life. He escapes from prison but things don't go as planned...\ngenres: DramaCrimeComedy\nposter: https://image.tmdb.org/t/p/w500/ojDg0PGvs6R9xYFodRct2kdI6wC.jpg\nrelease_date: 593395200\n"
}
  1. Rendering a document from an index on an inline document template
request
// POST /render-template

{
  "template": {
    "kind": "inlineDocumentTemplate",
    "inline": "You can pass templates inline as well: nice to test them! {{doc.id}}"
  },
  "input": {
    "kind": "indexDocument",
    "indexUid": "movies",
    "id": "2"
}
response
{
  "template": "You can pass templates inline as well: nice to test them! {{doc.id}}",
  "rendered": "You can pass templates inline as well: nice to test them! 2"
}
  1. Rendering an inline document on an inline indexing fragment
request
// POST /render-template

{
  "template": {
    "kind": "inlineFragment",
    "inline": {
      "json_maps": "supported for fragments",
      "any_string": "is in liquid format: {{doc.test}}"
    }
  },
  "input": {
     "kind": "inlineDocument",
    "inline": {
      "test": true
    }
  }
}
response
{
  "template": {
    "json_maps": "supported for fragments",
    "any_string": "is in liquid format: {{doc.test}}"
  },
  "rendered": {
    "json_maps": "supported for fragments",
    "any_string": "is in liquid format: true"
  }
}

[Experimental] Only support foreign filters on retrieval routes

by @ManyTheFish in https://github.com/meilisearch/meilisearch/pull/6446

Foreign filters are meant to be used in a retrieval context (search, get document...), but all the actions related to writing or modifying a document could have several unexpected behaviors if foreign filters are accepted. We prefer forbidding the usage of this feature on the writing routes.

The following routes do not support Foreign-filter anymore:

Additional change: we now ensure that the experimental features are checked when parsing a filter

🪲 Bug fixes

🔒 Security

🔩 Miscellaneous

❤️ Thanks again to @genisis0x and @antcybersec

2026-06-15 15:47:22
MeiliSearch

v1.47.0 🦇

🌈 Enhancements

Search personalization on federated search

We now support using the search personalization feature on federated search requests.

Like page/hitPerPage or limit/offset, the personalization option must be specified in the federation attribute to work properly. Otherwise, an error will be returned reminding you to move the attribute in federation.

By @ManyTheFish in https://github.com/meilisearch/meilisearch/pull/6414

The new settings indexer is feature complete 🎉

  • We now better support the tokenizer-related settings
  • We improved the quality of the new settings indexer to enhance the engine's performance when changing the locales, the dictionary, synonyms, stop words, separator, and non-separator tokens.
  • This makes the new settings indexer feature-complete, meaning that, unless you set the MEILI_EXPERIMENTAL_NO_EDITION_2024_FOR_SETTINGS environment variable to true, all settings tasks can now be handled by the new settings indexer, bringing a better scaling behavior, much faster cancellation, and a more precise progress view.

By @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6409

Observability improvements

We expose more Prometheus metrics to improve observability, specifically to show more metrics on document throughput and ease debugging.

By @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6430

🦋 Fixes

🔒 Security

🔩 Misc. changes

Search implementation refactor

Refactor the search pipeline to mutualize the code. The new implementation will always perform a federated search under the hood, and then the output will be transformed into the expected route's output.

Noticeable changes from the user perspective:

  • Some error messages have been modified
  • Small breaking change: a few error codes change, such as MultiSearch<Error> <--> Search<Error>

Other changes

New Contributors

Full Changelog: https://github.com/meilisearch/meilisearch/compare/v1.46.1...v1.47.0

2026-06-08 23:48:39
MeiliSearch

v1.46.1 🦆

Queue documents fetch routes

Add an experimental feature, queueDocumentsFetch, forcing the routes GET indexes/:uid/documents and POST indexes/:uid/documents/fetch to wait in the search queue if there is no available thread to process them.

2026-06-08 16:18:24
MeiliSearch

v1.46.0 🦆

This release introduces fixes for a regression in v1.45.0, where we were batching deletions by filter with other deletions or additions. It also enables the new settings indexer to support more parameters, making the engine faster to index documents when those settings are specified.

✨ Enhancement

  • Support exact and disable on numbers in the new settings indexer by @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6398 Introduce support for exact words and disable-on-words parameters in the new settings indexer, making the engine more efficient when changing these settings.

  • Support computing prefixes in the new settings indexer by @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6391 Support for the prefix search settings in the new settings indexer, so that changing this parameter makes the engine more efficient.

🪲 Bug fixes

  • Better limit read bytes when creating the S3 multipart part by @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6405 This fixes an issue we had with the multipart part size by ensuring we never construct a part larger than the defined multipart part size. With this fix, we always create a multipart with the provided multipart part size, except for the last part. Thanks, @vidit-virmani, for the help investigating the issue.

  • Batch of documentDeletionByFilter with documentAdditionOrUpdate by @Kerollmops and @ManyTheFish in https://github.com/meilisearch/meilisearch/pull/6415 Correctly implement the support for auto-batching deletion by filter with document replacement and updates. This fixes a regression introduced in v1.45.0.

  • Fix a panic with incomplete filters by @Kerollmops in https://github.com/meilisearch/meilisearch/pull/6421 Fixes an internal panic when a filter is incomplete by returning an error instead.

🔒 Security

🔩 Miscellaneous