Skip to content

Releases: meilisearch/meilisearch

v1.16.0 🦚

04 Aug 12:40
a2c96d4
Compare
Choose a tag to compare

Meilisearch v1.16 introduces two main features: multimodal embeddings and a new /export route. Multimodal embeddings use AI-powered search to index images in addition to textual documents. The /export route simplifies migrating from a local Meilisearch instance to Meilisearch Cloud.

🧰 All official Meilisearch integrations (including SDKs, clients, and other tools) are compatible with this Meilisearch release. Integration deployment happens between 4 to 48 hours after a new version becomes available.

Some SDKs might not include all new features. Consult the project repository for detailed information. Is a feature you need missing from your chosen SDK? Create an issue letting us know you need it, or, for open-source karma points, open a PR implementing it (we'll love you for that ❤️).

New features and updates 🔥

Experimental feature: Multimodal embeddings

v1.16 allows indexing and searching non-textual documents, as well as performing searches with image queries. This new feature uses multimodal embedders to provide a common semantic representation for images, texts, and any other piece of data.

Usage

First, enable the multimodal experimental feature:

curl \
  -X PATCH 'MEILISEARCH_URL/experimental-features/' \
  -H 'Content-Type: application/json'  \
  --data-binary '{
    "multimodal": true
  }'

Next, pick an embedder provider that supports multimodal embeddings such as Cohere or VoyageAI to start building the embedding configuration.

The following is an example configuration for multimodal embedder using VoyageAI:

curl \
  -X PATCH 'MEILISEARCH_URL/indexes/INDEX_NAME/settings/embedders' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "voyage": {
      "source": "rest",
      "url": "https://api.voyageai.com/v1/multimodalembeddings",
      "apiKey": "VOYAGE_API_KEY",
      "indexingFragments": {
        "text": {
          "value": {
            "content": [
              {
                "type": "text",
                "text": "A movie titled {{doc.title}} whose description starts with {{doc.overview|truncateWords:20}}."
              }
            ]
          }
        },
        "poster": {
          "value": {
            "content": [
              {
                "type": "image_url",
                "image_url": "{{doc.poster}}"
              }
            ]
          }
        }
      },
      "searchFragments": {
        "poster": {
          "value": {
            "content": [
              {
                "type": "image_url",
                "image_url": "{{media.poster}}"
              }
            ]
          }
        },
        "image": {
          "value": {
            "content": [
              {
                "type": "image_base64",
                "image_base64": "data:{{media.image.mime}};base64,{{media.image.data}}"
              }
            ]
          }
        },
        "text": {
          "value": {
            "content": [
              {
                "type": "text",
                "text": "{{q}}"
              }
            ]
          }
        }
      },
      "request": {
        "inputs": [
          "{{fragment}}",
          "{{..}}"
        ],
        "model": "voyage-multimodal-3"
      },
      "response": {
        "data": [
          {
            "embedding": "{{embedding}}"
          },
          "{{..}}"
        ]
      }
    }}

The configuration above sets up Meilisearch to generate vectors for two fields: text and poster. It also allows users to perform searches with an image URL, a raw image, or regular text.

Use the new media search parameter together with one of the searchFragments you specified in your embedder to search with an image:

curl -X POST 'MEILISEARCH_URL/indexes/INDEX_NAME/search' \
  -H 'content-type: application/json' \
  --data-binary '{
    "media": {
      "poster": "https://image.tmdb.org/t/p/w500/pgqj7QoBPWFLLKtLEpPmFYFRMgB.jpg"
    },
    "hybrid": {
      "embedder": "EMBEDDER_NAME"
    }
  }'

You can also perform a text search with q and hybrid:

curl -X POST 'MEILISEARCH_URL/indexes/INDEX_NAME/search' \
  -H 'content-type: application/json' \
  --data-binary '{
    "q": "A movie with lightsabers in space",
    "hybrid": {
      "embedder": "voyage",
      "semanticRatio": 0.5
    }
  }'

Meilisearch performs searches all fields with embeddings when parsing hybrid queries targeting indexes with multimodal embedders.

For more information about this feature, please refer to its public usage page

Done by @dureuill in #5596

The new /export route

v1.16 introduces a new /export route that allows transferring documents between instances without having to create a dump or a snapshot. This feature is particularly useful when migrating from a local machine to Meilisearch Cloud.

Usage

To transfer data between instances, query /export and point its url parameter to the URL of the target instance:

curl \
  -X POST 'MEILISEARCH_URL/export' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "url": "http://localhost:7711"
  }'

This will generate an export and task start migrating data between instances. Depending on the target instance, you may also have to supply an API key with full admin permissions in the apiKey parameter. Consult the documentation for an exhaustive list of accepted parameters.

If the request fails, Meilisearch will retry a few times before setting its status to failed. You may also cancel an export task manually. In this case, Meilisearch will interrupt the task locally, but not in the target instance.

Done by @Kerollmops with the help of @Mubelotix in #5670

Other improvements

  • Add support for nested wildcards in attributes_to_search_on by @lblack00 in #5548
  • Improve support of geo field extraction from documents by @nnethercott in #5592
  • Use all CPUs when importing dumps by @nnethercott in #5527
  • Display the last embedder error live in batches by @Mubelotix in #5707
  • Add fallback instance option to revert to old indexer by @ManyTheFish in #5687
  • Introduce filters in the chat completions by @Kerollmops in #5710
  • Allow sorting on the /documents route by @Mubelotix in #5716
  • A Read-Only Admin key will be created in new empty databases, to prevent accidentally writing to database while investigating, by @Mubelotix in #5693
  • Use the edition 2024 documents indexer in the dumps by @Kerollmops in #5762

Fixes 🐞

  • Improve the performance when managing single-typo words by @dureuill in #5551
  • Fix distinct attribute functionality for hybrid search by @dureuill in #5614
  • Fix bug related to Cyrillic having different typo tolerance due to byte counting bug by @arthurgousset in #5617
  • Fix Gemini base_url when used with OpenAI clients by @diksipav in #5692
  • Remove Gemini from LLM-providers list due to incompatibility with OpenAI by @Kerollmops in #5708
  • Fix bug when using the environment variable for --experimental-limit-batched-tasks-total-size by @Kerollmops in #5705
  • Fix disableOnNumbers not being affected by typo tolerance settings resets by @Nymuxyzo in #5702
  • Make sure to recover from missing update files by @Kerollmops in #5683
  • Add analytics to chat completions by @Kerollmops in #5709
  • Fix: Preserve order of searchable attributes when modified by @ManyTheFish in #5751
  • Fix Total Hits being wrong when rankingScoreThreshold is used by @Mubelotix in #5725
  • Fix incorrect document count in stats after clearing all documents by @kametsun in #5754
  • Fix chat settings dumpless upgrade by @Kerollmops in #5761
  • Fix panic when attempting to remove an embedder that does not exist by @Mubelotix in #5734
  • Fixes an issue where sending searchParameters: {} in index chat settings would incorrectly set the limit to 20 instead of resetting to empty defaults
  • Update the mini-dashboard to v0.2.22 and fix a crash by @Kerollmops in #5798

Misc

  • Dependencies updates
  • CIs and tests (34 PRs, one folk, yes!)
    • perf: Faster IT tests - stats.rs by @Mar...
Read more

v1.16.0-rc.5 🦚

01 Aug 07:14
6f8c414
Compare
Choose a tag to compare
v1.16.0-rc.5 🦚 Pre-release
Pre-release

Warning

Since this is a release candidate (RC), we do NOT recommend using it in a production environment. Is something not working as expected? We welcome bug reports and feedback about new features.

What's Changed

Full Changelog: v1.16.0-rc.4...v1.16.0-rc.5

v1.16.0-rc.4 🦚

28 Jul 14:04
d4c88f2
Compare
Choose a tag to compare
v1.16.0-rc.4 🦚 Pre-release
Pre-release

Warning

Since this is a release candidate (RC), we do NOT recommend using it in a production environment. Is something not working as expected? We welcome bug reports and feedback about new features.

🐛 Bugfixes

  • Fix API keys when using dumpless upgrade to v1.16.0 by @Mubelotix in #5780
  • fix: index chat settings searchParameters incorrectly set with limit: 20 when sending empty object by @nicolasvienot in #5770

New Contributors

Full Changelog: v1.16.0-rc.3...v1.16.0-rc.4

v1.16.0-rc.3 🦚

22 Jul 12:21
080d5f9
Compare
Choose a tag to compare
v1.16.0-rc.3 🦚 Pre-release
Pre-release

Warning

Since this is a release candidate (RC), we do NOT recommend using it in a production environment. Is something not working as expected? We welcome bug reports and feedback about new features.

What's Changed

  • Use the edition 2024 documents indexer in the dumps by @Kerollmops in #5762
  • Regenerate all fragments when coming from a user-provided vector by @dureuill in #5763

Full Changelog: v1.16.0-rc.2...v1.16.0-rc.3

v1.16.0-rc.2 🦚

18 Jul 08:41
0312fb2
Compare
Choose a tag to compare
v1.16.0-rc.2 🦚 Pre-release
Pre-release

Warning

Since this is a release candidate (RC), we do NOT recommend using it in a production environment. Is something not working as expected? We welcome bug reports and feedback about new features.

What's Changed

New Contributors

See also

v1.16.0-rc.1 🦚

10 Jul 07:37
faa1f7c
Compare
Choose a tag to compare
v1.16.0-rc.1 🦚 Pre-release
Pre-release

Warning

Since this is a release candidate (RC), we do NOT recommend using it in a production environment. Is something not working as expected? We welcome bug reports and feedback about new features.

🦋 Bug fixes

  • Fix the dumpless upgrade to v1.16 following the database changes introduced by the multimodal embedder feature, by @dureuill in #5737

Other improvements

  • A Read-Only Admin key will be created in new empty databases, to prevent accidentally writing to database while investigating, by @Mubelotix in #5693

See also

v1.16.0-rc.0 🦚

07 Jul 13:44
a803085
Compare
Choose a tag to compare
v1.16.0-rc.0 🦚 Pre-release
Pre-release

Warning

Since this is a release candidate (RC), we do NOT recommend using it in a production environment. Is something not working as expected? We welcome bug reports and feedback about new features.
⚠ In particular, upgrading from a database containing embeddings is known not to work in RC.0 ⚠

Meilisearch v1.16 introduces two core features, multimodal embeddings allowing to index images, text and other formats; and the Export/Transfer of documents between instances easing the migration of a local Meilisearch into the cloud!

New features and updates 🔥

Multimodal embeddings

Meilisearch now allows conveniently indexing images, text and other formats in documents, and to retrieve documents by searching with an image or a text query.

This new feature leverages multimodal embedders to provide a common semantic representation for images, texts, and any other piece of data in a format supported by the chosen model.

As an example, the sample movies dataset contains movie descriptions and links to movie posters. Using this new feature, it is possible to use text to search both in the descriptions and the posters, or to use an image to search for similar looking posters, or movies with a description matching the query image.

Usage

To use multimodal embeddings, start by enabling the multimodal experimental feature:

curl $MEILISEARCH_URL/experimental-features -X PATCH -H 'Content-type: application/json' -d '{"multimodal": true}'

Then pick an embedder service that supports multimodal such as cohere or VoyageAI to start building the embedding configuration.

An example configuration for VoyageAI to index the description and poster from the movies database, and to search by text or image, might look like the following:

// PATCH /indexes/$INDEX_NAME/settings/embedders
{"voyage": {
  "source": "rest",
  "url": "https://api.voyageai.com/v1/multimodalembeddings",
  "apiKey": "$VOYAGE_API_KEY",
  // describes how we index documents
  "indexingFragments": {
    "text": {
      "value": {
        // this part sticks to the voyage API <https://docs.voyageai.com/reference/multimodal-embeddings-api>
        "content": [
          {
            "type": "text",
            "text": "A movie titled {{doc.title}} whose description starts with {{doc.overview|truncateWords:20}}."
          }
        ]
      }
    },
    // we also send the poster
    "poster": {
      "value": {
        "content": [
          {
            "type": "image_url",
            "image_url": "{{doc.poster}}"
          }
        ]
      }
    }
  },
  // describes how to search in the index
  "searchFragments": {
    // we allow sending a poster at search time
    "poster": {
      "value": {
        "content": [
          {
            "type": "image_url",
            "image_url": "{{media.poster}}"
          }
        ]
      }
    },
    // we also allow inline image data at search time only
    "image": {
      "value": {
        "content": [
          {
            "type": "image_base64",
            "image_base64": "data:{{media.image.mime}};base64,{{media.image.data}}"
          }
        ]
      }
    },
    "text": {
      "value": {
        "content": [
          {
            "type": "text",
            // uses the `q` field from search queries
            "text": "{{q}}"
          }
        ]
      }
    }
  },
  "request": {
    "inputs": [
      "{{fragment}}",
      "{{..}}"
    ],
    "model": "voyage-multimodal-3"
  },
  "response": {
    "data": [
      {
        "embedding": "{{embedding}}"
      },
      "{{..}}"
    ]
  }
}}

Then, to search by poster (image URL):

// POST /indexes/$INDEX_NAME/search
{
  "media": {
    "poster": "https://image.tmdb.org/t/p/w500/6FfCtAuVAW8XJjZ7eWeLibRLWTw.jpg"
  },
  "hybrid": {
    "embedder": "voyage",
    // semanticRatio is specified here for explicitness,
    // but it would default to 1.0 if omitted, as we don't have a text query
    // (no "q") here.
    "semanticRatio": 1.0
  }
}

To search by image data (encoded as base64):

// POST /indexes/$INDEX_NAME/search

{
  "media": {
    "image": {
      "mime": "image/jpeg",
      // image bytes encoded as base64
      "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2w..."
    }
  "hybrid": {
    "embedder": "voyage",
  }
}

To search by text (performing a hybrid search):

// POST /indexes/$INDEX_NAME/search
{
  // note that since the model is multimodal, this will also compare the produced embedding
  // with the poster images from movie, so describing a poster image here could find the
  // associated movie
  "q": "A movie with lightsabers in space",
  "hybrid": {
    "embedder": "voyage",
    "semanticRatio": 0.5
  }
}

For more information about this feature, please refer to its public usage page

Done by @dureuill in #5596

Export/Transfer documents between instances

Meilisearch now allows to transfer documents from an instance to another without having to create a dump or a snapshot. This feature will ease the migration to the Cloud by streaming all the documents from a local instance to a cloud one.

Usage

We expose one single route on the instance which accepts a bunch of parameters.

  • url: Where do we want to send our settings and documents.
  • apiKey: (optional) The API key to have the rights to send those requests. Usually the master key of the remote machine.
  • payloadSize: (optional) A human readable size defining the size of the payloads to send. Defaults to 50 MiB.
  • indexes: (optional) A set of patterns of matching the indexes you want to export. If not defined, defaults to all indexes without filter.
  • filter: (optional) A filter defining the subset of documents to actually export.
  • overrideSettings: (optional, default false) When false, will not set settings nor update the primary key on indexes that already exist on the remote instance. Will still send the documents

POST: /export

{
  "url": "http://localhost:7711",
  "apiKey": null,
  "payloadSize": "123 MiB",
  "indexes": {
    "*": {
      "filter": null,
      "overrideSettings": true
    }
  }
}

Response:

{
  "taskUid": 2,
  "indexUid": null,
  "status": "enqueued",
  "type": "export",
  "enqueuedAt": "2025-06-26T12:54:10.785864Z"
}

One task can retry requests in case of failure (not indefinitely, though) and can also be canceled. However, keep in mind that canceling this export task will not cancel tasks received by the targeted Meilisearch instance.

Done by @Kerollmops with the help of @Mubelotix in #5670

Other improvements

Fixes 🐞

  • Improve the performance when managing single-typo words by @dureuill in #5551
  • Fix distinct for hybrid search by @dureuill in #5614
  • Fix a bug related to Cyrillic having different typo tolerance due to byte counting bug by @arthurgousset in #5617
  • Fix Gemini base_url when used with OpenAI clients by @diksipav in #5692
  • Remove Gemini from the LLM-providers list due to incompatibility with OpenAI by @Kerollmops in #5708
  • Fix the environment variable name of the experimental limit batched tasks total size feature by @Kerollmops in #5705
  • Fix disableOnNumbers reset by @Nymuxyzo in #5702
  • Make sure to recover from missing update files by @Kerollmops in #5683
  • Add analytics to the chat completions by @Kerollmops in #5709

Misc

Read more

v1.15.2 🦘

12 Jun 19:08
6b4d699
Compare
Choose a tag to compare

This patch release introduces a major fix and some minor fixes.

Major fix: searchable attributes database bug

Some searchable fields were removed from the searchable databases when they were removed from the filterableAttributes setting.
This made them unsearchable, although they were still precise in the searchableAttributes setting.

Fixed by @ManyTheFish in #5660

Minor fixes

v1.15.1 🦘

11 Jun 15:55
9275ce1
Compare
Choose a tag to compare

Meilisearch v1.15.1 adds new experimental conversational features and enables LLM-driven chat features.

🧰 All official Meilisearch integrations (including SDKs, clients, and other tools) are compatible with this Meilisearch release. Integration deployment takes 4 to 48 hours after a new version becomes available.

Some SDKs might not include all new features. Please look over the project repository for detailed information. Is a feature you need missing from your chosen SDK? Create an issue letting us know you need it, or, for open-source karma points, open a PR implementing it (we'll love you for that ❤️).

Chat with your indexes

After enabling the experimental chat feature, you can create a chat workspace with the appropriate settings.
We have a guide on how to set up a good chat interface for your indexes.

curl -X POST 'http://localhost:7700/chats/my-assistant/settings' \
  -H 'Content-Type: application/json' \
  -d '{
    "source": "openAi",
    "apiKey": "sk-abc..."
  }'

Then by using the official OpenAI SDK you'll be able to chat with your indexes.

import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:7700/chats/my-assistant',
  apiKey: 'YOUR_MEILISEARCH_CHAT_API_KEY',
});

const completion = await client.chat.completions.create({
  model: 'gpt-3.5-turbo',
  messages: [{ role: 'user', content: 'What is Meilisearch?' }],
  stream: true,
});

for await (const chunk of completion) {
  console.log(chunk.choices[0]?.delta?.content || '');
}

Done by @Kerollmops in #5556.

v1.15.0 🦘

09 Jun 10:07
7f5a0c0
Compare
Choose a tag to compare

Meilisearch v1.15 adds a new typo tolerance setting, allowing you to disable typo tolerance for numbers. It also enables comparison operators for string filters.

🧰 All official Meilisearch integrations (including SDKs, clients, and other tools) are compatible with this Meilisearch release. Integration deployment takes 4 to 48 hours after a new version becomes available.

Some SDKs might not include all new features. Please look over the project repository for detailed information. Is a feature you need missing from your chosen SDK? Create an issue letting us know you need it, or, for open-source karma points, open a PR implementing it (we'll love you for that ❤️).

New features and updates 🔥

Disable typo tolerance for numbers

Set typoTolerance.disableOnNumbers to true to disable typo tolerance for numbers:

curl -X POST 'http://localhost:7700/indexes/movies/settings' \
  -H 'Content-Type: application/json' \
  -d '{
    "typoTolerance": {"disableOnNumbers": true}
  }'

Deactivating the typo tolerance on numbers can be helpful when trying to reduce false positives, such as a query term 2024 returning results that include 2025 and 2004. It may also improve indexing performance.

Done by @ManyTheFish in #5494.

Lexicographic string filters

This release allows you to filter strings lexicographically by enabling comparison operators (<, <=, >, >=, TO) on string values:

curl -X POST 'http://localhost:7700/indexes/movies/search' \
  -H 'Content-Type: application/json' \
  -d '{
    "filter": "release_date >= '2024-06'"
  }'

This new feature can be particularly useful when filtering human-readable dates.

Done by @dureuill in #5535.

Other improvements

Fixes 🐞

  • Fix _matchesPosition length calculation to improve client-side cropping by @shaokeyibb in #5446
  • Fix _geo ranking rule by @HDT3213 in #5487
  • Fix a panic in the search that could happen when looking for typos with a search prefix having more than 65k possible hits in the DB by @dureuill in #5564
  • Make sure that passing MEILI_EXPERIMENTAL_MAX_NUMBER_OF_BATCHED_TASKS to 0 results in Meilisearch never processing any kind of task. By @irevoire in #5565
  • Forbid value 0 for maxTotalHits in the index settings by @irevoire in #5566
  • No longer reject documentTemplates that use array filters on documents (e.g. join) by @dureuill in #5593

Misc

❤️ Thanks again to our external contributors: