diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 87007b7a4..c117f564c 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -1467,6 +1467,18 @@ related_results_similar_1: |- "id": 192, "embedder": "EMBEDDER_NAME" }' +export_post_1: |- + curl \ + -X POST 'MEILISEARCH_URL/export' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "url": "TARGET_INSTANCE_URL", + "indexes": { + "*": { + "overrideSettings": true + } + } + }' ### Code samples for experimental features experimental_get_metrics_1: |- @@ -1533,3 +1545,19 @@ update_network_1: |- } } }' +search_parameter_reference_media_1: |- + curl \ + -X POST 'MEILISEARCH_URL/indexes/INDEX_NAME/search' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "hybrid": { + "embedder": "EMBEDDER_NAME" + }, + "media": { + "FIELD_A": "VALUE_A", + "FIELD_B" : { + "FIELD_C": "VALUE_B" + "FIELD_D": "VALUE_C" + } + } + }' diff --git a/assets/misc/meilisearch-collection-postman.json b/assets/misc/meilisearch-collection-postman.json index deb15aa68..dcf5fa694 100644 --- a/assets/misc/meilisearch-collection-postman.json +++ b/assets/misc/meilisearch-collection-postman.json @@ -1,7 +1,7 @@ { "info": { - "_postman_id": "b321d331-d809-4909-8e49-e29c8d749d32", - "name": "Meilisearch v1.15", + "_postman_id": "f4b62ec3-0403-44ba-b6f4-640badbbd1b2", + "name": "Meilisearch v1.16", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", "_exporter_id": "25294324" }, @@ -106,6 +106,11 @@ "key": "ids", "value": "1,2", "disabled": true + }, + { + "key": "sort", + "value": "\"price\"", + "disabled": true } ] } @@ -3159,6 +3164,60 @@ } ] }, + { + "name": "Export", + "item": [ + { + "name": "Migrate data to a remote instance", + "protocolProfileBehavior": { + "disabledSystemHeaders": {} + }, + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"url\": \"TARGET_INSTANCE_URL\",\n \"indexes\": {\n \"*\": {\n \"overrideSettings\": true\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}/export", + "host": [ + "{{url}}" + ], + "path": [ + "export" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, { "name": "Snapshots", "item": [ diff --git a/docs.json b/docs.json index a58aac938..e2ae21d7b 100644 --- a/docs.json +++ b/docs.json @@ -143,7 +143,7 @@ "navigation": { "versions": [ { - "version": "v1.15", + "version": "v1.16", "anchors": [ { "anchor": "Learn", @@ -165,7 +165,6 @@ "group": "AI-powered search", "pages": [ "learn/ai_powered_search/getting_started_with_ai_search", - "learn/ai_powered_search/conversational_search_with_chat", "learn/ai_powered_search/configure_rest_embedder", "learn/ai_powered_search/document_template_best_practices", "learn/ai_powered_search/image_search_with_user_provided_embeddings", @@ -175,6 +174,14 @@ "learn/ai_powered_search/difference_full_text_ai_search" ] }, + { + "group": "Conversational search", + "pages": [ + "learn/chat/getting_started_with_chat", + "learn/chat/chat_tooling_reference", + "learn/chat/conversational_search" + ] + }, { "group": "Self-hosted", "pages": [ @@ -342,7 +349,8 @@ "reference/api/dump", "reference/api/experimental_features", "reference/api/metrics", - "reference/api/logs" + "reference/api/logs", + "reference/api/export" ] }, { @@ -945,6 +953,14 @@ { "source": "/guides/deployment/gcp", "destination": "/guides/running_production" + }, + { + "source": "/guides/ai/getting_started_with_chat", + "destination": "/learn/chat/getting_started_with_chat" + }, + { + "source": "learn/ai_powered_search/conversational_search_with_chat", + "destination": "learn/chat/conversational_search" } ] } diff --git a/guides/docker.mdx b/guides/docker.mdx index 410bce2a4..76c0f6f08 100644 --- a/guides/docker.mdx +++ b/guides/docker.mdx @@ -12,7 +12,7 @@ Docker is a tool that bundles applications into containers. Docker containers en Docker containers are distributed in images. To use Meilisearch, use the `docker pull` command to download a Meilisearch image: ```sh -docker pull getmeili/meilisearch:v1.15 +docker pull getmeili/meilisearch:v1.16 ``` Meilisearch deploys a new Docker image with every release of the engine. Each image is tagged with the corresponding Meilisearch version, indicated in the above example by the text following the `:` symbol. You can see [the full list of available Meilisearch Docker images](https://hub.docker.com/r/getmeili/meilisearch/tags#!) on Docker Hub. @@ -29,7 +29,7 @@ After completing the previous step, use `docker run` to launch the Meilisearch i docker run -it --rm \ -p 7700:7700 \ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 + getmeili/meilisearch:v1.16 ``` ### Configure Meilisearch @@ -45,7 +45,7 @@ docker run -it --rm \ -p 7700:7700 \ -e MEILI_MASTER_KEY='MASTER_KEY'\ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 + getmeili/meilisearch:v1.16 ``` #### Passing instance options with CLI arguments @@ -56,7 +56,7 @@ If you want to pass command-line arguments to Meilisearch with Docker, you must docker run -it --rm \ -p 7700:7700 \ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 \ + getmeili/meilisearch:v1.16 \ meilisearch --master-key="MASTER_KEY" ``` @@ -74,7 +74,7 @@ To keep your data intact between reboots, specify a dedicated volume by running docker run -it --rm \ -p 7700:7700 \ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 + getmeili/meilisearch:v1.16 ``` The example above uses `$(pwd)/meili_data`, which is a directory in the host machine. Depending on your OS, mounting volumes from the host to the container might result in performance loss and is only recommended when developing your application. @@ -89,7 +89,7 @@ To import a dump, use Meilisearch's `--import-dump` command-line option and spec docker run -it --rm \ -p 7700:7700 \ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 \ + getmeili/meilisearch:v1.16 \ meilisearch --import-dump /meili_data/dumps/20200813-042312213.dump ``` @@ -109,7 +109,7 @@ To generate a Meilisearch snapshot with Docker, launch Meilisearch with `--sched docker run -it --rm \ -p 7700:7700 \ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 \ + getmeili/meilisearch:v1.16 \ meilisearch --schedule-snapshot --snapshot-dir /meili_data/snapshots ``` @@ -121,7 +121,7 @@ To import a snapshot, launch Meilisearch with the `--import-snapshot` option: docker run -it --rm \ -p 7700:7700 \ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 \ + getmeili/meilisearch:v1.16 \ meilisearch --import-snapshot /meili_data/snapshots/data.ms.snapshot ``` diff --git a/learn/chat/chat_tooling_reference.md b/learn/chat/chat_tooling_reference.md new file mode 100644 index 000000000..5485abb47 --- /dev/null +++ b/learn/chat/chat_tooling_reference.md @@ -0,0 +1,225 @@ +--- +title: Chat tooling reference +description: An exhaustive reference of special chat tools supported by Meilisearch +--- + +When creating your conversational search agent, you may be able to extend the model's capabilities with a number of tools. This page lists Meilisearch-specific tools that may improve user experience. + + +This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it: + +```sh +curl \ + -X PATCH 'MEILISEARCH_URL/experimental-features/' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "chatCompletions": true + }' +``` + + +## Meilisearch chat tools + +For the best user experience, configure all following tools. + +1. **Handle progress updates** by displaying search status to users during streaming +2. **Append conversation messages** as requested to maintain context for future requests +3. **Display source documents** to users for transparency and verification +4. **Use `call_id`** to associate progress updates with their corresponding source results + + +These special tools are handled internally by Meilisearch and are not forwarded to the LLM provider. They serve as a communication mechanism between Meilisearch and your application to provide enhanced user experience features. + + +### `_meiliSearchProgress` + +This tool reports real-time progress of internal search operations. When declared, Meilisearch will call this function whenever search operations are performed in the background. + +**Purpose**: Provides transparency about search operations and reduces perceived latency by showing users what's happening behind the scenes. + +**Arguments**: + +- `call_id`: Unique identifier to track the search operation +- `function_name`: Name of the internal function being executed (e.g., "_meiliSearchInIndex") +- `function_parameters`: JSON-encoded string containing search parameters like `q` (query) and `index_uid` + +**Example Response**: + +```json +{ + "function": { + "name": "_meiliSearchProgress", + "arguments": "{\"call_id\":\"89939d1f-6857-477c-8ae2-838c7a504e6a\",\"function_name\":\"_meiliSearchInIndex\",\"function_parameters\":\"{\\\"index_uid\\\":\\\"movies\\\",\\\"q\\\":\\\"search engine\\\"}\"}" + } +} +``` + +### `_meiliAppendConversationMessage` + +Since the `/chats/{workspace}/chat/completions` endpoint is stateless, this tool helps maintain conversation context by requesting the client to append internal messages to the conversation history. + +**Purpose**: Maintains conversation context for better response quality in subsequent requests by preserving tool calls and results. + +**Arguments**: + +- `role`: Message author role ("user" or "assistant") +- `content`: Message content (for tool results) +- `tool_calls`: Array of tool calls made by the assistant +- `tool_call_id`: ID of the tool call this message responds to + +**Example Response**: + +```json +{ + "function": { + "name": "_meiliAppendConversationMessage", + "arguments": "{\"role\":\"assistant\",\"tool_calls\":[{\"id\":\"call_ijAdM42bixq9lAF4SiPwkq2b\",\"type\":\"function\",\"function\":{\"name\":\"_meiliSearchInIndex\",\"arguments\":\"{\\\"index_uid\\\":\\\"movies\\\",\\\"q\\\":\\\"search engine\\\"}\"}}]}" + } +} +``` + +### `_meiliSearchSources` + +This tool provides the source documents that were used by the LLM to generate responses, enabling transparency and allowing users to verify information sources. + +**Purpose**: Shows users which documents were used to generate responses, improving trust and enabling source verification. + +**Arguments**: + +- `call_id`: Matches the `call_id` from `_meiliSearchProgress` to associate queries with results +- `documents`: JSON object containing the source documents with only displayed attributes + +**Example Response**: + +```json +{ + "function": { + "name": "_meiliSearchSources", + "arguments": "{\"call_id\":\"abc123\",\"documents\":[{\"id\":197302,\"title\":\"The Sacred Science\",\"overview\":\"Diabetes. Prostate cancer...\",\"genres\":[\"Documentary\",\"Adventure\",\"Drama\"]}]}" + } +} +``` + +### Sample OpenAI tool declaration + +Include these tools in your request's `tools` array to enable enhanced functionality: + + + +```json +{ + … + "tools": [ + { + "type": "function", + "function": { + "name": "_meiliSearchProgress", + "description": "Provides information about the current Meilisearch search operation", + "parameters": { + "type": "object", + "properties": { + "call_id": { + "type": "string", + "description": "The call ID to track the sources of the search" + }, + "function_name": { + "type": "string", + "description": "The name of the function we are executing" + }, + "function_parameters": { + "type": "string", + "description": "The parameters of the function we are executing, encoded in JSON" + } + }, + "required": ["call_id", "function_name", "function_parameters"], + "additionalProperties": false + }, + "strict": true + } + }, + { + "type": "function", + "function": { + "name": "_meiliAppendConversationMessage", + "description": "Append a new message to the conversation based on what happened internally", + "parameters": { + "type": "object", + "properties": { + "role": { + "type": "string", + "description": "The role of the messages author, either `role` or `assistant`" + }, + "content": { + "type": "string", + "description": "The contents of the `assistant` or `tool` message. Required unless `tool_calls` is specified." + }, + "tool_calls": { + "type": ["array", "null"], + "description": "The tool calls generated by the model, such as function calls", + "items": { + "type": "object", + "properties": { + "function": { + "type": "object", + "description": "The function that the model called", + "properties": { + "name": { + "type": "string", + "description": "The name of the function to call" + }, + "arguments": { + "type": "string", + "description": "The arguments to call the function with, as generated by the model in JSON format. Note that the model does not always generate valid JSON, and may hallucinate parameters not defined by your function schema. Validate the arguments in your code before calling your function." + } + } + }, + "id": { + "type": "string", + "description": "The ID of the tool call" + }, + "type": { + "type": "string", + "description": "The type of the tool. Currently, only function is supported" + } + } + } + }, + "tool_call_id": { + "type": ["string", "null"], + "description": "Tool call that this message is responding to" + } + }, + "required": ["role", "content", "tool_calls", "tool_call_id"], + "additionalProperties": false + }, + "strict": true + } + }, + { + "type": "function", + "function": { + "name": "_meiliSearchSources", + "description": "Provides sources of the search", + "parameters": { + "type": "object", + "properties": { + "call_id": { + "type": "string", + "description": "The call ID to track the original search associated to those sources" + }, + "documents": { + "type": "object", + "description": "The documents associated with the search (call_id). Only the displayed attributes of the documents are returned" + } + }, + "required": ["call_id", "documents"], + "additionalProperties": false + }, + "strict": true + } + } + ] +} +``` + + diff --git a/learn/ai_powered_search/conversational_search_with_chat.mdx b/learn/chat/conversational_search.mdx similarity index 65% rename from learn/ai_powered_search/conversational_search_with_chat.mdx rename to learn/chat/conversational_search.mdx index d8de0f76d..773cc2a22 100644 --- a/learn/ai_powered_search/conversational_search_with_chat.mdx +++ b/learn/chat/conversational_search.mdx @@ -1,18 +1,28 @@ --- -title: Conversational search with chat +title: Conversational search sidebarTitle: Conversational search description: Learn how to implement AI-powered conversational search using Meilisearch's chat feature --- Meilisearch's chat completions feature enables AI-powered conversational search, allowing users to ask questions in natural language and receive direct answers based on your indexed content. This feature transforms the traditional search experience into an interactive dialogue. - -The chat completions feature is experimental and must be enabled through [experimental features](/reference/api/experimental_features). API specifications may change in future releases. - + +This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it: + +```sh +curl \ + -X PATCH 'MEILISEARCH_URL/experimental-features/' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "chatCompletions": true + }' +``` + ## What is conversational search? -Conversational search allows users to: +Conversational search interfaces allow users to: + - Ask questions in natural language instead of using keywords - Receive direct answers rather than just document links - Maintain context across multiple questions @@ -23,53 +33,50 @@ This approach bridges the gap between traditional search and modern AI experienc ## How chat completions differs from traditional search ### Traditional search workflow + 1. User enters keywords 2. Meilisearch returns matching documents 3. User reviews results to find answers ### Conversational search workflow + 1. User asks a question in natural language 2. Meilisearch retrieves relevant documents 3. AI generates a direct answer based on those documents 4. User can ask follow-up questions -## RAG implementation simplified - -The chat completions feature implements a complete Retrieval Augmented Generation (RAG) pipeline in a single API endpoint. Traditional RAG implementations require: - -- Multiple LLM calls for query optimization -- Separate vector database for semantic search -- Custom reranking solutions -- Complex pipeline management - -Meilisearch's chat completions consolidates these into one streamlined process: - -1. **Query understanding**: Automatically transforms questions into optimal search parameters -2. **Hybrid retrieval**: Combines keyword and semantic search for superior relevance -3. **Answer generation**: Uses your chosen LLM to generate responses -4. **Context management**: Maintains conversation history automatically - ## When to use chat completions vs traditional search ### Use conversational search when: + - Users need direct answers to specific questions - Content is informational (documentation, knowledge bases, FAQs) - Users benefit from follow-up questions - Natural language interaction improves user experience ### Use traditional search when: + - Users need to browse multiple options - Results require comparison (e-commerce products, listings) - Exact matching is critical - Response time is paramount -## Alternative: Model Context Protocol integration +## Use chat completions to implement RAG pipelines + +The chat completions feature implements a complete Retrieval Augmented Generation (RAG) pipeline in a single API endpoint. Meilisearch's chat completions consolidates RAG creation into one streamlined process: + +1. **Query understanding**: automatically transforms questions into search parameters +2. **Hybrid retrieval**: combines keyword and semantic search for better relevancy +3. **Answer generation**: uses your chosen LLM to generate responses +4. **Context management**: maintains conversation history by constantly pushing the full conversation to the dedicated tool + +### Alternative: MCP integration When integrating Meilisearch with AI assistants and automation tools, consider using [Meilisearch's Model Context Protocol (MCP) server](/guides/ai/mcp). MCP enables standardized tool integration across various AI platforms and applications. ## Architecture overview -The chat completions feature operates through workspaces, which are isolated configurations for different use cases or tenants. Each workspace can: +Chat completions operate through workspaces, which are isolated configurations for different use cases. Each workspace can: - Use different LLM sources (openAi, azureOpenAi, mistral, gemini, vLlm) - Apply custom prompts @@ -97,13 +104,12 @@ The chat completions feature operates through workspaces, which are isolated con The chat completions feature integrates with Meilisearch's existing security model: -- **API key permissions**: Chat only accesses indexes visible to the provided API key -- **Tenant tokens**: Support for multi-tenant applications -- **LLM credentials**: Stored securely in workspace settings -- **Content isolation**: Responses based only on indexed content +- **API key permissions**: chat only accesses indexes visible to the provided API key +- **Tenant tokens**: support for multi-tenant applications +- **LLM credentials**: stored securely in workspace settings +- **Content isolation**: responses based only on indexed content ## Next steps -- [Get started with chat completions implementation](/guides/ai/getting_started_with_chat) +- [Get started with chat completions implementation](/learn/chat/getting_started_with_chat) - [Explore the chat completions API reference](/reference/api/chats) -- [Learn about experimental features](/reference/api/experimental_features) diff --git a/guides/ai/getting_started_with_chat.mdx b/learn/chat/getting_started_with_chat.mdx similarity index 59% rename from guides/ai/getting_started_with_chat.mdx rename to learn/chat/getting_started_with_chat.mdx index 689c9c119..1288decd0 100644 --- a/guides/ai/getting_started_with_chat.mdx +++ b/learn/chat/getting_started_with_chat.mdx @@ -6,62 +6,47 @@ description: Learn how to implement AI-powered conversational search in your app This guide walks you through implementing Meilisearch's chat completions feature to create conversational search experiences in your application. - -The chat completions feature is experimental and must be enabled before use. See [experimental features](/reference/api/experimental_features) for activation instructions. - - ## Prerequisites Before starting, ensure you have: -- Meilisearch instance running (v1.15.1 or later) **with a master key** (required for authentication) -- An API key from an LLM provider (OpenAI, Azure OpenAI, Mistral, Gemini, or access to a vLLM server) +- A [secure](/learn/security/basic_security) Meilisearch >= v1.15.1 project +- An API key from an LLM provider - At least one index with searchable content -- The chat completions experimental feature enabled - - -**Important**: You MUST start Meilisearch with a master key to enable authentication. Without it, the chat feature will not work properly. - -Example: `meilisearch --master-key yourMasterKey` - -In some versions, you may also need to add the `--experimental-enable-chat` flag when starting Meilisearch. - -## Quick start - -### Enable the chat completions feature +## Enable the chat completions feature First, enable the chat completions experimental feature: ```bash curl \ -X PATCH 'http://localhost:7700/experimental-features/' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "chatCompletions": true }' ``` -### Find your chat API key +## Find your chat API key When Meilisearch runs with a master key, it automatically creates a "Default Chat API Key" with `chatCompletions` permission. Find it using: ```bash curl http://localhost:7700/keys \ - -H "Authorization: Bearer " + -H "Authorization: Bearer MEILISEARCH_KEY" ``` -Look for the key with "Default Chat API Key" in the description. You'll use this key (or the master key) for chat endpoint requests. +Look for the key with "Default Chat API Key" in the description. Use this key when queryin the `/chats` endpoint. -### Configure your indexes for chat +## Configure your indexes for chat Each index that you want to be searchable through chat needs specific configuration: ```bash curl \ -X PATCH 'http://localhost:7700/indexes/movies/settings' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "chat": { @@ -77,7 +62,7 @@ curl \ The `description` field helps the LLM understand what data is in the index, improving search relevance. -### Configure a chat completions workspace +## Configure a chat completions workspace Create a workspace with your LLM provider settings. Here are examples for different providers: @@ -86,7 +71,7 @@ Create a workspace with your LLM provider settings. Here are examples for differ ```bash openAi curl \ -X PUT 'http://localhost:7700/chats/my-assistant/settings' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "openAi", @@ -101,7 +86,7 @@ curl \ ```bash azureOpenAi curl \ -X PUT 'http://localhost:7700/chats/my-assistant/settings' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "azureOpenAi", @@ -116,7 +101,7 @@ curl \ ```bash mistral curl \ -X PUT 'http://localhost:7700/chats/my-assistant/settings' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "mistral", @@ -130,7 +115,7 @@ curl \ ```bash gemini curl \ -X PUT 'http://localhost:7700/chats/my-assistant/settings' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "gemini", @@ -144,7 +129,7 @@ curl \ ```bash vLlm curl \ -X PUT 'http://localhost:7700/chats/my-assistant/settings' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "vLlm", @@ -157,7 +142,7 @@ curl \ -### Send your first chat completions request +## Send your first chat completions request Now you can start a conversation. Note the `-N` flag for handling streaming responses: @@ -174,28 +159,32 @@ curl -N \ "content": "What movies do you have about space exploration?" } ], - "stream": true + "stream": true, + "tools": [ + { + "type": "function", + "function": { + "name": "_meiliSearchProgress", + "description": "Reports real-time search progress to the user" + } + }, + { + "type": "function", + "function": { + "name": "_meiliSearchSources", + "description": "Provides sources and references for the information" + } + } + ] }' ``` - -Currently, only streaming responses (`stream: true`) are supported. Non-streaming responses are not yet available and will result in an error. - - -## Understanding workspaces - -Workspaces allow you to create isolated chat configurations for different use cases: +Take particular note of the `tools` array. These settings are optional, but greatly improve user experience: -- **Customer support**: Configure with support-focused prompts -- **Product search**: Optimize for e-commerce queries -- **Documentation**: Tune for technical Q&A +- **`_meiliSearchProgress`**: shows users what searches are being performed +- **`_meiliSearchSources`**: displays the actual documents used to generate responses -Each workspace maintains its own: - -- LLM provider configuration -- System prompt - -## Building a chat interface with OpenAI SDK +## Build a chat interface using the OpenAI SDK Since Meilisearch's chat endpoint is OpenAI-compatible, you can use the official OpenAI SDK: @@ -261,9 +250,9 @@ for await (const chunk of stream) { -## Error handling +### Error handling -When using the OpenAI SDK with Meilisearch's chat completions endpoint, errors from the streamed responses are natively handled by the official OpenAI SDK. This means you can use the SDK's built-in error handling mechanisms without additional configuration: +When using the OpenAI SDK with Meilisearch's chat completions endpoint, errors from the streamed responses are natively handled by OpenAI. This means you can use the SDK's built-in error handling mechanisms without additional configuration: @@ -272,7 +261,7 @@ import OpenAI from 'openai'; const client = new OpenAI({ baseURL: 'http://localhost:7700/chats/my-assistant', - apiKey: 'YOUR_CHAT_API_KEY', + apiKey: 'MEILISEARCH_KEY', }); try { @@ -296,7 +285,7 @@ from openai import OpenAI client = OpenAI( base_url="http://localhost:7700/chats/my-assistant", - api_key="YOUR_CHAT_API_KEY" + api_key="MEILISEARCH_KEY" ) try: @@ -316,52 +305,6 @@ except Exception as error: -## Enabling database search with Meilisearch tools - - -**Critical**: Without including the Meilisearch tools in your request, the chat will only use the LLM's general knowledge and won't search your actual Meilisearch indexes! - - -To make the chat search your Meilisearch indexes, you must include these special tools in your request: - -```bash -curl -N \ - -X POST 'http://localhost:7700/chats/my-assistant/chat/completions' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - --data-binary '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "What movies do you have about space exploration?" - } - ], - "stream": true, - "tools": [ - { - "type": "function", - "function": { - "name": "_meiliSearchProgress", - "description": "Reports real-time search progress to the user" - } - }, - { - "type": "function", - "function": { - "name": "_meiliSearchSources", - "description": "Provides sources and references for the information" - } - } - ] - }' -``` - -These tools enable: - -- **`_meiliSearchProgress`**: Shows users what searches are being performed -- **`_meiliSearchSources`**: Provides the actual documents used to generate responses - ## Troubleshooting ### Common issues and solutions @@ -388,7 +331,7 @@ These tools enable: - Use either the master key or the "Default Chat API Key" - Don't use search or admin API keys for chat endpoints -- Find your chat key: `curl http://localhost:7700/keys -H "Authorization: Bearer "` +- Find your chat key: `curl http://localhost:7700/keys -H "Authorization: Bearer MEILISEARCH_KEY"` #### "Socket connection closed unexpectedly" @@ -400,14 +343,14 @@ These tools enable: ```bash curl http://localhost:7700/chats/my-assistant/settings \ - -H "Authorization: Bearer " + -H "Authorization: Bearer MEILISEARCH_KEY" ``` 2. Update with valid API key: ```bash curl -X PUT http://localhost:7700/chats/my-assistant/settings \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer MEILISEARCH_KEY" \ -H "Content-Type: application/json" \ -d '{"apiKey": "your-valid-api-key"}' ``` @@ -430,113 +373,8 @@ These tools enable: - Always set `"stream": true` in your requests - Non-streaming responses are not yet supported -## Complete working example - -Here's a full example showing the complete setup process: - -### Step 1: Start Meilisearch with authentication - -```bash -meilisearch --master-key myMasterKey123 -``` - -### Step 2: Enable experimental features - -```bash -curl -X PATCH 'http://localhost:7700/experimental-features/' \ - -H 'Authorization: Bearer myMasterKey123' \ - -H 'Content-Type: application/json' \ - -d '{"chatCompletions": true}' -``` - -### Step 3: Create and populate an index - -```bash -# Create index -curl -X POST 'http://localhost:7700/indexes' \ - -H 'Authorization: Bearer myMasterKey123' \ - -H 'Content-Type: application/json' \ - -d '{"uid": "movies", "primaryKey": "id"}' - -# Add documents -curl -X POST 'http://localhost:7700/indexes/movies/documents' \ - -H 'Authorization: Bearer myMasterKey123' \ - -H 'Content-Type: application/json' \ - -d '[ - {"id": 1, "title": "Interstellar", "description": "A team of explorers travel through a wormhole in space"}, - {"id": 2, "title": "The Martian", "description": "An astronaut becomes stranded on Mars"} - ]' -``` - -### Step 4: Configure index for chat - -```bash -curl -X PATCH 'http://localhost:7700/indexes/movies/settings' \ - -H 'Authorization: Bearer myMasterKey123' \ - -H 'Content-Type: application/json' \ - -d '{ - "chat": { - "description": "A movie database with titles and descriptions", - "documentTemplate": "Title: {{ title }}\nDescription: {{ description }}\n", - "documentTemplateMaxBytes": 400 - } - }' -``` - -### Step 5: Create chat workspace - -```bash -curl -X PUT 'http://localhost:7700/chats/movie-advisor/settings' \ - -H 'Authorization: Bearer myMasterKey123' \ - -H 'Content-Type: application/json' \ - -d '{ - "source": "openAi", - "apiKey": "sk-your-openai-key", - "prompts": { - "system": "You are a movie recommendation assistant. Help users find movies based on their preferences." - } - }' -``` - -### Step 6: Get your chat API key - -```bash -curl http://localhost:7700/keys \ - -H "Authorization: Bearer myMasterKey123" \ - | grep -A 5 "Default Chat API Key" -``` - -### Step 7: Make a chat request with tools - -```bash -curl -N -X POST 'http://localhost:7700/chats/movie-advisor/chat/completions' \ - -H 'Authorization: Bearer ' \ - -H 'Content-Type: application/json' \ - -d '{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "What space movies do you have?"}], - "stream": true, - "tools": [ - { - "type": "function", - "function": { - "name": "_meiliSearchProgress", - "description": "Reports search progress" - } - }, - { - "type": "function", - "function": { - "name": "_meiliSearchSources", - "description": "Provides source documents" - } - } - ] - }' -``` - ## Next steps - Explore [advanced chat API features](/reference/api/chats) -- Learn about [conversational search concepts](/learn/ai_powered_search/conversational_search_with_chat) -- Review [security best practices](/learn/security/basic_security) +- Learn about [conversational search concepts](/learn/chat/conversational_search) +- Review [security best practices](/learn/security/basic_security) \ No newline at end of file diff --git a/learn/resources/experimental_features_overview.mdx b/learn/resources/experimental_features_overview.mdx index c245ee2aa..1ec5ebc81 100644 --- a/learn/resources/experimental_features_overview.mdx +++ b/learn/resources/experimental_features_overview.mdx @@ -59,3 +59,6 @@ Activating or deactivating experimental features this way does not require you t | [Search query embedding cache](/learn/self_hosted/configure_meilisearch_at_launch#search-query-embedding-cache) | Enable a cache for search query embeddings | CLI flag or environment variable | | [Uncompressed snapshots](/learn/self_hosted/configure_meilisearch_at_launch#uncompressed-snapshots) | Disable snapshot compaction | CLI flag or environment variable | | [Maximum batch payload size](/learn/self_hosted/configure_meilisearch_at_launch#maximum-batch-payload-size) | Limit batch payload size | CLI flag or environment variable | +| [Multimodal search](/reference/api/settings) | Enable multimodal search | API route | +| [Disable new indexer](/learn/self_hosted/configure_meilisearch_at_launch) | Use previous settings indexer | CLI flag or environment variable | + diff --git a/learn/resources/telemetry.mdx b/learn/resources/telemetry.mdx index 263e55d4b..93674e8e9 100644 --- a/learn/resources/telemetry.mdx +++ b/learn/resources/telemetry.mdx @@ -225,6 +225,8 @@ This list is liable to change with every new version of Meilisearch. It's not be | `infos.experimental_edit_documents_by_function` | `true` if the `editDocumentsByFunction` experimental feature is enabled | false | `infos.experimental_enable_metrics` | `true` if `--experimental-enable-metrics` is specified at launch | false | `infos.experimental_embedding_cache_entries` | Size of configured embedding cache | 100 +| `infos.experimental_multimodal` | `true` when multimodal search feature is enabled | true | +| `infos.experimental_no_edition_2024_for_settings` | `true` if instance disabled new indexer | false | `infos.experimental_replication_parameters` | `true` if `--experimental-replication-parameters` is specified at launch | false | `infos.experimental_reduce_indexing_memory_usage` | `true` if `--experimental-reduce-indexing-memory-usage` is specified at launch | false | `infos.experimental_logs_mode` | `human` or `json` depending on the value specified | human @@ -248,6 +250,7 @@ This list is liable to change with every new version of Meilisearch. It's not be | `vector.retrieve_vectors` | `true` if the retrieve_vectors parameter has been used in this batch. | false | `hybrid.enabled` | `true` if hybrid search been used in the aggregated event | true | `hybrid.semantic_ratio` | `true` if semanticRatio was used in this batch, otherwise false | false +| `hybrid.total_media` | Aggregated number of search requests where `media` is not `null` | 42 | `embedders.total` | Numbers of defined embedders | 2 | `embedders.sources` | An array representing the different provided sources | ["huggingFace", "userProvided"] | `embedders.document_template_used` | A boolean indicating if one of the provided embedders has a custom template defined | true @@ -264,3 +267,9 @@ This list is liable to change with every new version of Meilisearch. It's not be | `experimental_network` | `true` when the network experimental feature is enabled | true | `remotes.total_distinct_remote_count` | Sum of the number of distinct remotes appearing in each search request of the aggregate | 48 | `remotes.avg_distinct_remote_count` | Average number of distinct remotes appearing in a search request of the aggregate | 2.33 +| `multimodal` | `true` when multimodal search is enabled via the `/experimental-features` route | true +| `export.total_received` | Number of exports received in this batch | `152` +| `export.has_api_key` | Number of exports with an API Key set | `89` +| `export.avg_index_patterns` | Average number of index patterns set per export | `3.2` +| `export.avg_patterns_with_filter` | Average number of index patterns with filters per export | `1.7` +| `export.avg_payload_size` | Average payload size per export | `512` diff --git a/learn/self_hosted/configure_meilisearch_at_launch.mdx b/learn/self_hosted/configure_meilisearch_at_launch.mdx index 48d9540b7..5bd0c3dc1 100644 --- a/learn/self_hosted/configure_meilisearch_at_launch.mdx +++ b/learn/self_hosted/configure_meilisearch_at_launch.mdx @@ -538,6 +538,18 @@ Helps running Meilisearch in cluster environments. It does this by modifying tas - Allows you to manually set task uids by adding a custom `TaskId` header to your API requests - Allows you to dry register tasks by specifying a `DryRun: true` header in your request +### Disable new indexer + + +🚩 This option does not take any values. Assigning a value will throw an error. 🚩 + + +**Environment variable**: `MEILI_EXPERIMENTAL_NO_EDITION_2024_FOR_SETTINGS`
+**CLI option**: `--experimental-no-edition-2024-for-settings`
+**Default value**: `None`
+ +Falls back to previous settings indexer. + ### SSL options #### SSL authentication path diff --git a/learn/self_hosted/install_meilisearch_locally.mdx b/learn/self_hosted/install_meilisearch_locally.mdx index c93fc9ddc..7cb35f5f6 100644 --- a/learn/self_hosted/install_meilisearch_locally.mdx +++ b/learn/self_hosted/install_meilisearch_locally.mdx @@ -53,14 +53,14 @@ These commands launch the **latest stable release** of Meilisearch. ```bash # Fetch the latest version of Meilisearch image from DockerHub -docker pull getmeili/meilisearch:v1.15 +docker pull getmeili/meilisearch:v1.16 # Launch Meilisearch in development mode with a master key docker run -it --rm \ -p 7700:7700 \ -e MEILI_ENV='development' \ -v $(pwd)/meili_data:/meili_data \ - getmeili/meilisearch:v1.15 + getmeili/meilisearch:v1.16 # Use ${pwd} instead of $(pwd) in PowerShell ``` diff --git a/package.json b/package.json index 0ff347d2d..d7134aae3 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "1.15.0", + "version": "1.16.0", "homepage": "https://meilisearch.com/docs", "license": "MIT", "repository": "meilisearch/documentation", diff --git a/reference/api/batches.mdx b/reference/api/batches.mdx index a9e48c97c..b73a32222 100644 --- a/reference/api/batches.mdx +++ b/reference/api/batches.mdx @@ -48,7 +48,12 @@ The `/batches` route gives information about the progress of batches of [asynchr }, "progressTrace": { … }, "writeChannelCongestion": { … }, - "internalDatabaseSizes": { … } + "internalDatabaseSizes": { … }, + "embedderRequests": { + "total": 12, + "failed": 5, + "lastError": "runtime error: received internal error HTTP 500 from embedding server\n - server replied with `{\"error\":\"Service Unavailable\"}`" + } }, "duration": "PT0.250518S", "startedAt": "2024-12-10T15:20:30.18182Z", @@ -123,6 +128,12 @@ Object containing information on write operations computed during indexing. Can Size of each internal database, including by how much it changed after a batch was processed. +#### `embedderRequests` + +Object containing the total number of requests made to the embedder. Also displays the number of failed requests, if any, along with the error message for the most recent failure. + +Only present in batches with at least one task querying an embedder. This field continuously updates until Meilisearch finishes processing the batch. + ### `duration` **Type**: String
@@ -219,7 +230,12 @@ For example, `?uids=0` returns a batch containing the task with a `taskUid` equa }, "progressTrace": { … }, "writeChannelCongestion": { … }, - "internalDatabaseSizes": { … } + "internalDatabaseSizes": { … }, + "embedderRequests": { + "total": 12, + "failed": 5, + "lastError": "runtime error: received internal error HTTP 500 from embedding server\n - server replied with `{\"error\":\"Service Unavailable\"}`" + } }, "duration": "PT0.110083S", "startedAt": "2024-12-10T15:49:04.995321Z", @@ -270,6 +286,14 @@ Get a single batch. }, "indexUids": { "INDEX_NAME": 1 + }, + "progressTrace": { … }, + "writeChannelCongestion": { … }, + "internalDatabaseSizes": { … }, + "embedderRequests": { + "total": 12, + "failed": 5, + "lastError": "runtime error: received internal error HTTP 500 from embedding server\n - server replied with `{\"error\":\"Service Unavailable\"}`" } }, "duration": "PT0.364788S", diff --git a/reference/api/chats.mdx b/reference/api/chats.mdx index 07f62d525..7b11a158e 100644 --- a/reference/api/chats.mdx +++ b/reference/api/chats.mdx @@ -1,12 +1,12 @@ --- title: Chats sidebarTitle: Chats -description: The /chats route allows you to create conversational search experiences using LLM technology +description: Use the chat completion API to create conversational search experiences using LLM technology --- import { RouteHighlighter } from '/snippets/route_highlighter.mdx'; -The `/chats` route enables AI-powered conversational search by integrating Large Language Models (LLMs) with your Meilisearch data. This feature allows users to ask questions in natural language and receive contextual answers based on your indexed content. +The `/chats` route enables AI-powered conversational search by integrating Large Language Models (LLMs) with your Meilisearch data. This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it: @@ -19,30 +19,100 @@ curl \ "chatCompletions": true }' ``` - -## Chat completions workspace object +## Authorization + +When working with a secure Meilisearch instance, Use an API key with access to both the `search` and `chatCompletions` actions, such as the default chat API key. + +Chat queries only search indexes its API key can access. The default chat API key has access to all indexes. To limit chat access to specific indexes, you must either create a new key, or [generate a tenant token](/learn/security/generate_tenant_token_sdk) from the default chat API key. + +## Chat workspace object ```json { - "uid": "customer-support" + "uid": "WORKSPACE_NAME" } ``` -| Name | Type | Description | -| :---------- | :----- | :-------------------------------------------------- | +| Name | Type | Description | +| :---------- | :----- | :--------------------------------------------------- | | **`uid`** | String | Unique identifier for the chat completions workspace | -## Update the chat workspace settings +## List chat workspaces - + - -Both `PUT` and `PATCH` methods are supported. The first call to either method will create the workspace UID if it doesn't already exist. `PUT` replaces the entire configuration, while `PATCH` updates only the provided fields. - +List all chat workspaces. Results can be paginated by using the `offset` and `limit` query parameters. -Configure the LLM provider and settings for a chat workspace. +### Query parameters + +| Query parameter | Description | Default value | +| :-------------- | :----------------------------- | :------------ | +| **`offset`** | Number of workspaces to skip | `0` | +| **`limit`** | Number of workspaces to return | `20` | + +### Response + +| Name | Type | Description | +| :------------ | :------ | :----------------------------------- | +| **`results`** | Array | An array of [workspaces](#chat-workspace-object) | +| **`offset`** | Integer | Number of workspaces skipped | +| **`limit`** | Integer | Number of workspaces returned | +| **`total`** | Integer | Total number of workspaces | + +### Example + +```sh + curl \ + -X GET 'MEILISEARCH_URL/chats?limit=3' +``` + +#### Response: `200 Ok` + +```json +{ + "results": [ + { "uid": "WORKSPACE_1" }, + { "uid": "WORKSPACE_2" }, + { "uid": "WORKSPACE_3" } + ], + "offset": 0, + "limit": 20, + "total": 3 +} +``` + +## Get one chat workspace + + + +Get information about a workshop. + +### Path parameters + +| Name | Type | Description | +| :---------------- | :----- | :------------------------------------------------------------------------ | +| **`workspace_uid`** * | String | `uid` of the requested index | + +### Example + +```sh + curl \ + -X GET 'MEILISEARCH_URL/chats/WORKSPACE_UID' +``` + +#### Response: `200 Ok` + +```json +{ + "uid": "WORKSPACE_UID" +} +``` + +## Chat workspace settings + +### Chat workspace settings object ```json { @@ -59,13 +129,67 @@ Configure the LLM provider and settings for a chat workspace. } ``` -### Path parameters +#### The prompts object + +| Name | Type | Description | +| :------------------------ | :----- | :---------------------------------------------------------------- | +| **`system`** | String | A prompt added to the start of the conversation to guide the LLM | +| **`searchDescription`** | String | A prompt to explain what the internal search function does | +| **`searchQParam`** | String | A prompt to explain what the `q` parameter of the search function does and how to use it | +| **`searchIndexUidParam`** | String | A prompt to explain what the `indexUid` parameter of the search function does and how to use it | + +### Get chat workspace settings + + + +Retrieve the current settings for a chat workspace. + +#### Path parameters + +| Name | Type | Description | +| :-------------- | :----- | :----------------------------------- | +| **`workspace_uid`** | String | The workspace identifier | + +#### Response: `200 OK` + +Returns the settings object. For security reasons, the `apiKey` field is obfuscated. + +```json +{ + "source": "openAi", + "prompts": { + "system": "You are a helpful assistant." + } +} +``` + +#### Example + + + +```bash cURL +curl \ + -X GET 'http://localhost:7700/chats/WORKSPACE_UID/settings' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' +``` + + + +### Update chat workspace settings + + + +Configure the LLM provider and settings for a chat workspace. + +If the workspace does not exist, querying this endpoint will create it. + +#### Path parameters | Name | Type | Description | | :-------------- | :----- | :----------------------------------- | -| **`workspace`** | String | The workspace identifier | +| **`workspace_uid`** | String | The workspace identifier | -### Settings parameters +#### Settings parameters | Name | Type | Description | | :---------------- | :----- | :---------------------------------------------------------------------------- | @@ -78,41 +202,32 @@ Configure the LLM provider and settings for a chat workspace. | **`apiKey`** | String | API key for the LLM provider (optional for vLlm) | | **`prompts`** | Object | Prompts object containing system prompts and other configuration | -### The prompts object - -| Name | Type | Description | -| :------------------------ | :----- | :---------------------------------------------------------------- | -| **`system`** | String | A prompt added to the start of the conversation to guide the LLM | -| **`searchDescription`** | String | A prompt to explain what the internal search function does | -| **`searchQParam`** | String | A prompt to explain what the `q` parameter of the search function does and how to use it | -| **`searchIndexUidParam`** | String | A prompt to explain what the `indexUid` parameter of the search function does and how to use it | - -### Request body +#### Request body ```json { "source": "openAi", - "apiKey": "sk-...", + "apiKey": "OPEN_AI_API_KEY", "prompts": { - "system": "You are a helpful assistant." + "system": "DEFAULT CHAT INSTRUCTIONS" } } ``` All fields are optional. Only provided fields will be updated. -### Response: `200 OK` +#### Response: `200 OK` -Returns the updated settings object. Note that `apiKey` is write-only and will not be returned in the response. +Returns the updated settings object. `apiKey` is write-only and will not be returned in the response. -### Examples +#### Examples ```bash openAi curl \ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \ - -H 'Authorization: Bearer MASTER_KEY' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "openAi", @@ -126,7 +241,7 @@ curl \ ```bash azureOpenAi curl \ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \ - -H 'Authorization: Bearer MASTER_KEY' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "azureOpenAi", @@ -144,7 +259,7 @@ curl \ ```bash mistral curl \ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \ - -H 'Authorization: Bearer MASTER_KEY' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "mistral", @@ -158,7 +273,7 @@ curl \ ```bash gemini curl \ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \ - -H 'Authorization: Bearer MASTER_KEY' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "gemini", @@ -172,7 +287,7 @@ curl \ ```bash vLlm curl \ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \ - -H 'Authorization: Bearer MASTER_KEY' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "source": "vLlm", @@ -185,11 +300,48 @@ curl \ +### Reset chat workspace settings + + + +Reset a chat workspace's settings to its default values. + +#### Path parameters + +| Name | Type | Description | +| :-------------- | :----- | :----------------------------------- | +| **`workspace_uid`** | String | The workspace identifier | + +#### Response: `200 OK` + +Returns the settings object without the `apiKey` field. + +```json +{ + "source": "openAi", + "prompts": { + "system": "You are a helpful assistant." + } +} +``` + +#### Example + + + +```bash cURL +curl \ + -X DELETE 'http://localhost:7700/chats/customer-support/settings' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' +``` + + + ## Chat completions - + -Create a chat completion using the OpenAI-compatible interface. The endpoint searches relevant indexes and generates responses based on the retrieved content. +Create a chat completion using Meilisearch's OpenAI-compatible interface. The endpoint searches relevant indexes and generates responses based on the retrieved content. ### Path parameters @@ -219,7 +371,7 @@ Create a chat completion using the OpenAI-compatible interface. The endpoint sea | **`stream`** | Boolean | No | Enable streaming responses (default: `true`) | -Currently, only streaming responses (`stream: true`) are supported. Non-streaming responses will be available in a future release. +Currently, only streaming responses (`stream: true`) are supported. ### Message object @@ -305,324 +457,3 @@ for chunk in stream: ``` - -## Get chat settings - - - -Retrieve the current settings for a chat workspace. - -### Path parameters - -| Name | Type | Description | -| :-------------- | :----- | :----------------------------------- | -| **`workspace`** | String | The workspace identifier | - -### Response: `200 OK` - -Returns the settings object without the `apiKey` field. - -```json -{ - "source": "openAi", - "prompts": { - "system": "You are a helpful assistant." - } -} -``` - -### Example - - - -```bash cURL -curl \ - -X GET 'http://localhost:7700/chats/customer-support/settings' \ - -H 'Authorization: Bearer MASTER_KEY' -``` - - - -## List chat workspaces - - - -List all available chat workspaces. Results can be paginated using query parameters. - -### Query parameters - -| Query parameter | Description | Default value | -| :-------------- | :----------------------------- | :------------ | -| **`offset`** | Number of workspaces to skip | `0` | -| **`limit`** | Number of workspaces to return | `20` | - -### Response - -| Name | Type | Description | -| :------------ | :------ | :---------------------------------------- | -| **`results`** | Array | An array of chat workspace objects | -| **`offset`** | Integer | Number of workspaces skipped | -| **`limit`** | Integer | Number of workspaces returned | -| **`total`** | Integer | Total number of workspaces | - -### Example - - - -```bash cURL -curl \ - -X GET 'http://localhost:7700/chats?limit=10' \ - -H 'Authorization: Bearer MASTER_KEY' -``` - - - -#### Response: `200 OK` - -```json -{ - "results": [ - { - "uid": "customer-support" - }, - { - "uid": "internal-docs" - } - ], - "offset": 0, - "limit": 10, - "total": 2 -} -``` - -## Authentication - -The chat feature integrates with Meilisearch's authentication system: - -- **Default Chat API Key**: A new default key is created when chat is enabled, with permissions to access chat endpoints -- **Tenant tokens**: Fully supported for multi-tenant applications -- **Index visibility**: Chat searches only indexes accessible with the provided API key - -## Tool calling - -The chat feature uses internal tool calling to search your indexes and provide enhanced user experience. For optimal performance and user experience, you should declare three special tools in your chat completion requests. These tools are handled internally by Meilisearch and provide real-time feedback about search operations, conversation context, and source documents. - -### Overview of Special Tools - -- **`_meiliSearchProgress`**: Reports real-time search progress and operations -- **`_meiliAppendConversationMessage`**: Maintains conversation context for better responses -- **`_meiliSearchSources`**: Provides source documents used in generating responses - -### Tool Declaration - -Include these tools in your request's `tools` array to enable enhanced functionality: - - - -```json Complete Tool Declaration -{ - "model": "gpt-3.5-turbo", - "stream": true, - "messages": [ - { - "role": "user", - "content": "What is Meilisearch?" - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "_meiliSearchProgress", - "description": "Provides information about the current Meilisearch search operation", - "parameters": { - "type": "object", - "properties": { - "call_id": { - "type": "string", - "description": "The call ID to track the sources of the search" - }, - "function_name": { - "type": "string", - "description": "The name of the function we are executing" - }, - "function_parameters": { - "type": "string", - "description": "The parameters of the function we are executing, encoded in JSON" - } - }, - "required": ["call_id", "function_name", "function_parameters"], - "additionalProperties": false - }, - "strict": true - } - }, - { - "type": "function", - "function": { - "name": "_meiliAppendConversationMessage", - "description": "Append a new message to the conversation based on what happened internally", - "parameters": { - "type": "object", - "properties": { - "role": { - "type": "string", - "description": "The role of the messages author, either `role` or `assistant`" - }, - "content": { - "type": "string", - "description": "The contents of the `assistant` or `tool` message. Required unless `tool_calls` is specified." - }, - "tool_calls": { - "type": ["array", "null"], - "description": "The tool calls generated by the model, such as function calls", - "items": { - "type": "object", - "properties": { - "function": { - "type": "object", - "description": "The function that the model called", - "properties": { - "name": { - "type": "string", - "description": "The name of the function to call" - }, - "arguments": { - "type": "string", - "description": "The arguments to call the function with, as generated by the model in JSON format. Note that the model does not always generate valid JSON, and may hallucinate parameters not defined by your function schema. Validate the arguments in your code before calling your function." - } - } - }, - "id": { - "type": "string", - "description": "The ID of the tool call" - }, - "type": { - "type": "string", - "description": "The type of the tool. Currently, only function is supported" - } - } - } - }, - "tool_call_id": { - "type": ["string", "null"], - "description": "Tool call that this message is responding to" - } - }, - "required": ["role", "content", "tool_calls", "tool_call_id"], - "additionalProperties": false - }, - "strict": true - } - }, - { - "type": "function", - "function": { - "name": "_meiliSearchSources", - "description": "Provides sources of the search", - "parameters": { - "type": "object", - "properties": { - "call_id": { - "type": "string", - "description": "The call ID to track the original search associated to those sources" - }, - "documents": { - "type": "object", - "description": "The documents associated with the search (call_id). Only the displayed attributes of the documents are returned" - } - }, - "required": ["call_id", "documents"], - "additionalProperties": false - }, - "strict": true - } - } - ] -} -``` - - - -### Tool Functions Explained - -#### `_meiliSearchProgress` - -This tool reports real-time progress of internal search operations. When declared, Meilisearch will call this function whenever search operations are performed in the background. - -**Purpose**: Provides transparency about search operations and reduces perceived latency by showing users what's happening behind the scenes. - -**Arguments**: - -- `call_id`: Unique identifier to track the search operation -- `function_name`: Name of the internal function being executed (e.g., "_meiliSearchInIndex") -- `function_parameters`: JSON-encoded string containing search parameters like `q` (query) and `index_uid` - -**Example Response**: - -```json -{ - "function": { - "name": "_meiliSearchProgress", - "arguments": "{\"call_id\":\"89939d1f-6857-477c-8ae2-838c7a504e6a\",\"function_name\":\"_meiliSearchInIndex\",\"function_parameters\":\"{\\\"index_uid\\\":\\\"movies\\\",\\\"q\\\":\\\"search engine\\\"}\"}" - } -} -``` - -#### `_meiliAppendConversationMessage` - -Since the `/chats/{workspace}/chat/completions` endpoint is stateless, this tool helps maintain conversation context by requesting the client to append internal messages to the conversation history. - -**Purpose**: Maintains conversation context for better response quality in subsequent requests by preserving tool calls and results. - -**Arguments**: - -- `role`: Message author role ("user" or "assistant") -- `content`: Message content (for tool results) -- `tool_calls`: Array of tool calls made by the assistant -- `tool_call_id`: ID of the tool call this message responds to - -**Example Response**: - -```json -{ - "function": { - "name": "_meiliAppendConversationMessage", - "arguments": "{\"role\":\"assistant\",\"tool_calls\":[{\"id\":\"call_ijAdM42bixq9lAF4SiPwkq2b\",\"type\":\"function\",\"function\":{\"name\":\"_meiliSearchInIndex\",\"arguments\":\"{\\\"index_uid\\\":\\\"movies\\\",\\\"q\\\":\\\"search engine\\\"}\"}}]}" - } -} -``` - -#### `_meiliSearchSources` - -This tool provides the source documents that were used by the LLM to generate responses, enabling transparency and allowing users to verify information sources. - -**Purpose**: Shows users which documents were used to generate responses, improving trust and enabling source verification. - -**Arguments**: - -- `call_id`: Matches the `call_id` from `_meiliSearchProgress` to associate queries with results -- `documents`: JSON object containing the source documents with only displayed attributes - -**Example Response**: - -```json -{ - "function": { - "name": "_meiliSearchSources", - "arguments": "{\"call_id\":\"abc123\",\"documents\":[{\"id\":197302,\"title\":\"The Sacred Science\",\"overview\":\"Diabetes. Prostate cancer...\",\"genres\":[\"Documentary\",\"Adventure\",\"Drama\"]}]}" - } -} -``` - -### Implementation Best Practices - -1. **Always declare all three tools** for the best user experience -2. **Handle progress updates** by displaying search status to users during streaming -3. **Append conversation messages** as requested to maintain context for future requests -4. **Display source documents** to users for transparency and verification -5. **Use the `call_id`** to associate progress updates with their corresponding source results - - -These special tools are handled internally by Meilisearch and are not forwarded to the LLM provider. They serve as a communication mechanism between Meilisearch and your application to provide enhanced user experience features. - diff --git a/reference/api/documents.mdx b/reference/api/documents.mdx index ab49ac0ac..4d8381b99 100644 --- a/reference/api/documents.mdx +++ b/reference/api/documents.mdx @@ -48,6 +48,8 @@ Use `offset` and `limit` to browse through documents. | **`fields`** | Array of strings/`null` | `*` | Document attributes to show (case-sensitive, comma-separated) | | **`filter`** | String/Array of array of strings/`null` | N/A | Refine results based on attributes in the `filterableAttributes` list | | **`retrieveVectors`** | Boolean | `false` | Return document vector data with search result | +| **`sort`** | `null` | A list of attributes written as an array or as a comma-separated string | + | **`ids`** | Array of primary keys | `null` | Return documents based on their primary keys | @@ -137,6 +139,7 @@ Using the query parameters `offset` and `limit`, you can browse through all your | **`fields`** | `*` | Document attributes to show (case-sensitive, comma-separated) | | **`filter`** | N/A | Refine results based on attributes in the `filterableAttributes` list | | **`retrieveVectors`** | `false` | Return document vector data with search result | +| **`sort`** | `null` | A list of comma-separated attributes | | **`ids`** | `null` | Return documents based on their primary keys | ### Response diff --git a/reference/api/experimental_features.mdx b/reference/api/experimental_features.mdx index 3393ceed9..b03cd95b6 100644 --- a/reference/api/experimental_features.mdx +++ b/reference/api/experimental_features.mdx @@ -26,7 +26,8 @@ The experimental API route is not compatible with all experimental features. Con "containsFilter": false, "editDocumentsByFunction": false, "network": false, - "chatCompletions": false + "chatCompletions": false, + "multimodal": false } ``` @@ -38,6 +39,7 @@ The experimental API route is not compatible with all experimental features. Con | **`editDocumentsByFunction`** | Boolean | `true` if feature is active, `false` otherwise | | **`network`** | Boolean | `true` if feature is active, `false` otherwise | | **`chatCompletions`** | Boolean | `true` if feature is active, `false` otherwise | +| **`multimodal`** | Boolean | `true` if feature is active, `false` otherwise | ## Get all experimental features @@ -58,7 +60,8 @@ Get a list of all experimental features that can be activated via the `/experime "containsFilter": false, "editDocumentsByFunction": false, "network": false, - "chatCompletions": false + "chatCompletions": false, + "multimodal": false } ``` @@ -87,6 +90,7 @@ Setting a field to `null` leaves its value unchanged. "containsFilter": false, "editDocumentsByFunction": false, "network": false, - "chatCompletions": false + "chatCompletions": false, + "multimodal": false } ``` diff --git a/reference/api/export.mdx b/reference/api/export.mdx new file mode 100644 index 000000000..5356ff58a --- /dev/null +++ b/reference/api/export.mdx @@ -0,0 +1,68 @@ +--- +title: Export +description: "Migrate between instances with the `/export` route" +--- + +import { RouteHighlighter } from '/snippets/route_highlighter.mdx' + +import CodeSamplesExperimentalDeleteLogsStream1 from '/snippets/samples/code_samples_experimental_delete_logs_stream_1.mdx'; + +Use the `/export` route to transfer data from your origin instance to a remote target instance. This is particularly useful when migrating from your local development environment to a Meilisearch Cloud instance. + +## Migrate database between instances + + + +Migrate data from the origin instance to a target instance. + +Migration is an additive operation. If the exported indexes already exist in the target instance, Meilisearch keeps the existing documents intact and adds the new data to the index. If the same document is present in both the target and origin, Meilisearch replaces the target documents with the new data. + +### Body + +| Name | Type | Default value | Description | +| ------------------- | ------ | ------------- | --------------------------------------------------------------------------------------------------------- | +| **`url`** * | String | `null` | The target instance's URL address. Required | +| **`apiKey`** * | String | `null` | An API key with full admin access to the target instance | +| **`payloadSize`** * | String | "50 MiB" | A string specifying the payload size in a human-readable format | +| **`indexes`** * | Object | `null` | A set of patterns matching the indexes you want to export. Defaults to all indexes in the origin instance | + +#### `url` + +A string pointing to a remote Meilisearch instance, including its port if necessary. + +This field is required. + +#### `apiKey` + +A security key with `index.create`, `settings.update`, and `documents.add` permissions to a secured Meilisearch instance. + +#### `payloadSize` + +The maximum size of each single data payload in a human-readable format such as `"100MiB"`. Larger payloads are generally more efficient, but require significantly more powerful machines. + +#### `indexes` + +A set of objects whose keys correspond to patterns matching the indexes you want to export. By default, Meilisearch exports all documents across all indexes. + +Meilisearch does not override any index settings by default. If the target instance contains an index with the same name as an index you're exporting, Meilisearch uses the settings in the target instance. If the index does not already exist in the target instance, Meilisearch uses the settings in the origin instance. + +Each index object accepts the following fields: + +- `filter`: a [filter expression](/learn/filtering_and_sorting/filter_expression_reference) defining the subset of documents to export. Optional, defaults to `null` +- `overrideSettings`: if `true`, configures indexes in the target instance with the origin instance settings. Optional, defaults to `false` + +### Example + + + +#### Response + +```json +{ + "taskUid": 2, + "indexUid": null, + "status": "enqueued", + "type": "export", + "enqueuedAt": "2025-06-26T12:54:10.785864Z" +} +``` diff --git a/reference/api/network.mdx b/reference/api/network.mdx index 4a456c42b..cacac632b 100644 --- a/reference/api/network.mdx +++ b/reference/api/network.mdx @@ -88,7 +88,7 @@ Do not enable the `network` feature if you rely on the value of attributes not p ## Get the network object - + Returns the current value of the instance's network object. @@ -116,7 +116,7 @@ Returns the current value of the instance's network object. ## Update the network object - + Update the `self` and `remotes` fields of the network object. diff --git a/reference/api/search.mdx b/reference/api/search.mdx index c5aeafa0b..cea475198 100644 --- a/reference/api/search.mdx +++ b/reference/api/search.mdx @@ -97,6 +97,7 @@ By default, [this endpoint returns a maximum of 1000 results](/learn/resources/k | **[`vector`](#vector)** | Array of numbers | `null` | Search using a custom query vector | | **[`retrieveVectors`](#display-_vectors-in-response)** | Boolean | `false` | Return document vector data | | **[`locales`](#query-locales)** | Array of strings | `null` | Explicitly specify languages used in a query | +| **[`media`](#media)** | Object | `null` | Perform AI-powered search queries with multimodal content | ### Response @@ -1141,7 +1142,9 @@ Excludes results below the specified ranking score. Excluded results do not count towards `estimatedTotalHits`, `totalHits`, and facet distribution. -For performance reasons, if the number of documents above `rankingScoreThreshold` is higher than `limit`, Meilisearch does not evaluate the ranking score of the remaining documents. Results ranking below the threshold are not immediately removed from the set of candidates. In this case, Meilisearch may overestimate the count of `estimatedTotalHits`, `totalHits` and facet distribution. +Using `rankingScoreThreshold` with `page` and `hitsPerPage` forces Meilisearch to evaluate the ranking score of all matching documents to return an accurate `totalHits`. This may negatively impact search performance. + +Queries with `limit` and `offset` avoid this overhead when using `rankingScoreThreshold`. #### Example @@ -1283,3 +1286,46 @@ For full control over the way Meilisearch detects languages during indexing and … } ``` + +### Media + +**Parameter**: `media`
+**Expected value**: Object
+**Default value**: `null` + + +This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it: + +```sh +curl \ + -X PATCH 'MEILISEARCH_URL/experimental-features/' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "multimodal": true + }' +``` + + +Specifies data to populate search fragments when performing multimodal searches. + +`media` must be an object whose fields must correspond to the data required by one [search fragment](/reference/api/settings#searchfragments). `media` must match a single search fragment. If `media` matches more than one fragment or no search fragments at all, Meilisearch will return an error. + +It is mandatory to specify an embedder when using `media`. `media` is incompatible with `vector`. + +#### Example + + + +```json +{ + "hits": [ + { + "id": 0, + "title": "DOCUMENT NAME", + … + } + … + ], + … +} +``` diff --git a/reference/api/settings.mdx b/reference/api/settings.mdx index ad7845256..3737fd50d 100644 --- a/reference/api/settings.mdx +++ b/reference/api/settings.mdx @@ -2512,7 +2512,9 @@ These embedder objects may contain the following fields: | **`binaryQuantized`** | Boolean | Empty | Once set to `true`, irreversibly converts all vector dimensions to 1-bit values | | **`indexingEmbedder`** | Object | Empty | Configures embedder to vectorize documents during indexing | | **`searchEmbedder`** | Object | Empty | Configures embedder to vectorize search queries | -| **`pooling`** | String | `"useModel"` | Pooling method for Hugging Face embedders | +| **`pooling`** | String | `"useModel"` | Pooling method for Hugging Face embedders | +| **`indexingFragments`** | Object | Empty | Configures multimodal embedding generation at indexing time | +| **`searchFragments`** | Object | Empty | Configures data handling during multimodal search | ### Get embedder settings @@ -2875,6 +2877,118 @@ Both fields must be an object and accept the same fields as a regular embedder, `indexingEmbedder` and `searchEmbedder` are incompatible with all other embedder sources. +##### `indexingFragments` + + +This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it: + +```sh +curl \ + -X PATCH 'MEILISEARCH_URL/experimental-features/' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "multimodal": true + }' +``` + + +`indexingFragments` specifies which fields in your documents should be used to generate multimodal embeddings. It must be an object with the following structure: + +```json + "FRAGMENT_NAME": { + "value": { + … + } + } +``` + +`FRAGMENT_NAME` can be any valid string. It must contain a single field, `value`. `value` must then follow your chosen model's specifications. + +For example, for [VoyageAI's multimodal embedding route](https://docs.voyageai.com/reference/multimodal-embeddings-api), `value` must be an object containing a `content` field. `content` itself must contain an array of objects with a `type` field. Depending on `type`'s value, you must include either `text`, `image_url`, or `image_base64`: + +```json +{ + "VOYAGE_FRAGMENT_NAME_A": { + "value": { + "content": [ + { + "type": "text", + "text": "A document called {{doc.title}} that can be described as {{doc.description}}" + } + ] + } + }, + "VOYAGE_FRAGMENT_NAME_B": { + "value": { + "content": [ + { + "type": "image_url", + "image_url": "{{doc.image_url}}" + } + ] + } + }, +} +``` + +Use Liquid templates to interpolate document data into the fragment fields, where `doc` gives you access to all fields within a document. + +`indexingFragments` is optional when using the `rest` source. + +`indexingFragments` is incompatible with all other embedder sources. + +Specifying a `documentTemplate` in an embedder using `indexingFragments` will result in an error. + +You must specify at least one valid fragment in `searchFragments` when using `indexingFragments`. + +##### `searchFragments` + + +This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it: + +```sh +curl \ + -X PATCH 'MEILISEARCH_URL/experimental-features/' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "multimodal": true + }' +``` + + +`searchFragments` instructs Meilisearch how to parse fields present in a query's [`media` search parameter](/reference/api/search#media). It must be an object following the same structure as the [`indexingFragments`](/reference/api/settings#indexingfragments) object: + +```json + "FRAGMENT_NAME": { + "value": { + … + } + } +``` + +As with `indexingFragments`, the content of `value` should follow your model's specification. + +Use Liquid templates to interpolate search query data into the fragment fields, where `media` gives you access to all multimodal data received with a query: + +```json +"SEARCH_FRAGMENT_A": { + "value": { + "content": [ + { + "type": "image_base64", + "image_base64": "data:{{media.image.mime}};base64,{{media.image.data}}" + } + ] + } +}, +``` + +`searchFragments` is optional when using the `rest` source. + +`searchFragments` is incompatible with all other embedder sources. + +You must specify at least one valid fragment in `indexingFragments` when using `searchFragments`. + #### Example @@ -2933,7 +3047,7 @@ This is an experimental feature. Use the Meilisearch Cloud UI or the experimenta ```sh curl \ -X PATCH 'http://localhost:7700/experimental-features/' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_API_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "chatCompletions": true @@ -2942,12 +3056,10 @@ curl \
-The chat settings allow you to configure how your index integrates with Meilisearch's conversational search feature. This enables the chat completions endpoint to search your index and generate responses based on your documents. +The chat settings allow you to configure how your index integrates with Meilisearch's conversational search feature. ### Chat object -The chat object in the index settings contains multiple settings to configure the conversational querying. - ```json { "description": "A comprehensive movie database containing titles, overviews, genres, and release dates to help users find movies", @@ -2964,14 +3076,14 @@ The chat object may contain the following fields: | Name | Type | Default Value | Description | | ------------------------------ | ------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------- | -| **`description`** | String | Empty | The description of the index. Used to help the LLM decide which index to use when generating answers | +| **`description`** | String | Empty | The description of the index. Helps the LLM decide which index to use when generating answers | | **`documentTemplate`** | String | `{% for field in fields %} {% if field.is_searchable and not field.value == nil %}{{ field.name }}: {{ field.value }} {% endif %} {% endfor %}` | Template defining the data Meilisearch sends to the LLM | | **`documentTemplateMaxBytes`** | Integer | 400 | Maximum allowed size of rendered document template | | **`searchParameters`** | Object | Empty | The search parameters to use when LLM is performing search requests | ### Search parameters object -Corresponds to a subset of the [search parameters object](/reference/api/search#search-parameters-object): +Must be one of the following [search parameters](/reference/api/search#search-parameters-object): - **`hybrid`** - **`limit`** @@ -2998,7 +3110,7 @@ Get the index chat settings configured for an index. ```bash curl \ -X GET 'http://localhost:7700/indexes/movies/settings/chat' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer MEILISEARCH_KEY' ``` ##### Response: `200 OK` @@ -3014,7 +3126,7 @@ curl \ ### Update index chat settings - + Partially update the index chat settings for an index. @@ -3034,10 +3146,10 @@ Partially update the index chat settings for an index. "searchParameters": { "hybrid": , "limit": , - "sort": , + "sort": [, , … ], "distinct": , "matchingStrategy": , - "attributesToSearchOn": , + "attributesToSearchOn": [, , … ], "rankingScoreThreshold": , } } @@ -3048,7 +3160,7 @@ Partially update the index chat settings for an index. ```bash curl \ -X PATCH 'http://localhost:7700/indexes/movies/settings/chat' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer MEILISEARCH_KEY' \ -H 'Content-Type: application/json' \ --data-binary '{ "description": "A comprehensive movie database containing titles, descriptions, genres, and release dates to help users find movies", diff --git a/reference/errors/error_codes.mdx b/reference/errors/error_codes.mdx index ddd649862..48c5448d5 100644 --- a/reference/errors/error_codes.mdx +++ b/reference/errors/error_codes.mdx @@ -146,6 +146,14 @@ The given [`uid`](/reference/api/keys#uid) is invalid. The `uid` must follow the The value passed to [`attributesToSearchOn`](/reference/api/search#customize-attributes-to-search-on-at-search-time) is invalid. `attributesToSearchOn` accepts an array of strings indicating document attributes. Attributes given to `attributesToSearchOn` must be present in the [`searchableAttributes` list](/learn/relevancy/displayed_searchable_attributes#the-searchableattributes-list). +## `invalid_search_media` + +The value passed to [`media`](/reference/api/search#media) is not a valid JSON object. + +## `invalid_search_media_and_vector` + +The search query contains non-`null` values for both [`media`](/reference/api/search#media) and [`vector`](/reference/api/search#media). These two parameters are mutually exclusive, since `media` generates vector embeddings via the embedder configured in `hybrid`. + ## `invalid_content_type` The [Content-Type header](/reference/api/overview#content-type) is not supported by Meilisearch. Currently, Meilisearch only supports JSON, CSV, and NDJSON. @@ -180,10 +188,38 @@ The [`limit`](/reference/api/documents#query-parameters) parameter is invalid. I The [`offset`](/reference/api/documents#query-parameters) parameter is invalid. It should be an integer. +## `invalid_document_sort` + +This error occurs if: + +- The syntax for the [`sort`](/reference/api/documents#body) parameter is invalid +- The attribute used for sorting is not defined in the [`sortableAttributes`](/reference/api/settings#sortable-attributes) list or the `sort` ranking rule is missing from the settings +- A reserved keyword like `_geo`, `_geoDistance`, `_geoRadius`, or `_geoBoundingBox` is used as a filter + ## `invalid_document_geo_field` The provided `_geo` field of one or more documents is invalid. Meilisearch expects `_geo` to be an object with two fields, `lat` and `lng`, each containing geographic coordinates expressed as a string or floating point number. Read more about `_geo` and how to troubleshoot it in [our dedicated guide](/learn/filtering_and_sorting/geosearch). +## `invalid_export_url` + +The export target instance URL is invalid or could not be reached. + +## `invalid_export_api_key` + +The supplied security key does not have the required permissions to access the target instance. + +## `invalid_export_payload_size` + +The provided payload size is invalid. The payload size must be a string indicating the maximum payload size in a human-readable format. + +## `invalid_export_indexes_patterns` + +The provided index pattern is invalid. The index pattern must be an alphanumeric string, optionally including a wildcard. + +## `invalid_export_index_filter` + +The provided index export filter is not a valid [filter expression](/learn/filtering_and_sorting/filter_expression_reference). + ## `invalid_facet_search_facet_name` The attribute used for the `facetName` field is either not a string or not defined in the [`filterableAttributes` list](/reference/api/settings#filterable-attributes). diff --git a/snippets/samples/code_samples_add_movies_json_1.mdx b/snippets/samples/code_samples_add_movies_json_1.mdx index 414246df0..068206c70 100644 --- a/snippets/samples/code_samples_add_movies_json_1.mdx +++ b/snippets/samples/code_samples_add_movies_json_1.mdx @@ -59,7 +59,7 @@ file, _ := os.ReadFile("movies.json") var movies interface{} json.Unmarshal([]byte(file), &movies) -client.Index("movies").AddDocuments(&movies) +client.Index("movies").AddDocuments(&movies, nil) ``` ```csharp C# diff --git a/snippets/samples/code_samples_add_or_replace_documents_1.mdx b/snippets/samples/code_samples_add_or_replace_documents_1.mdx index 13ae38b9d..7d9fb5a7f 100644 --- a/snippets/samples/code_samples_add_or_replace_documents_1.mdx +++ b/snippets/samples/code_samples_add_or_replace_documents_1.mdx @@ -80,7 +80,7 @@ documents := []map[string]interface{}{ "release_date": "2019-03-23", }, } -client.Index("movies").AddDocuments(documents) +client.Index("movies").AddDocuments(documents, nil) ``` ```csharp C# diff --git a/snippets/samples/code_samples_add_or_update_documents_1.mdx b/snippets/samples/code_samples_add_or_update_documents_1.mdx index a3c1cd3dd..53a1dd526 100644 --- a/snippets/samples/code_samples_add_or_update_documents_1.mdx +++ b/snippets/samples/code_samples_add_or_update_documents_1.mdx @@ -66,7 +66,7 @@ documents := []map[string]interface{}{ "genres": "comedy", }, } -client.Index("movies").UpdateDocuments(documents) +client.Index("movies").UpdateDocuments(documents, nil) ``` ```csharp C# diff --git a/snippets/samples/code_samples_async_guide_filter_by_statuses_1.mdx b/snippets/samples/code_samples_async_guide_filter_by_statuses_1.mdx index 5f67d39c0..609fe90cb 100644 --- a/snippets/samples/code_samples_async_guide_filter_by_statuses_1.mdx +++ b/snippets/samples/code_samples_async_guide_filter_by_statuses_1.mdx @@ -42,7 +42,7 @@ await client.GetTasksAsync(new TasksQuery { Statuses = new List ```rust Rust let mut query = TasksQuery::new(&client); let tasks = query - .with_statuses(["failed", "canceled"]) + .with_statuses(["failed"]) .execute() .await .unwrap(); diff --git a/snippets/samples/code_samples_async_guide_filter_by_statuses_2.mdx b/snippets/samples/code_samples_async_guide_filter_by_statuses_2.mdx index 53e8fd2b4..985a91b0b 100644 --- a/snippets/samples/code_samples_async_guide_filter_by_statuses_2.mdx +++ b/snippets/samples/code_samples_async_guide_filter_by_statuses_2.mdx @@ -4,4 +4,13 @@ curl \ -X GET 'MEILISEARCH_URL/tasks?statuses=failed,canceled' ``` + +```rust Rust +let mut query = TasksQuery::new(&client); +let tasks = query + .with_statuses(["failed", "canceled"]) + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_basic_security_tutorial_admin_1.mdx b/snippets/samples/code_samples_basic_security_tutorial_admin_1.mdx index ea0c45fb6..e0c803c2b 100644 --- a/snippets/samples/code_samples_basic_security_tutorial_admin_1.mdx +++ b/snippets/samples/code_samples_basic_security_tutorial_admin_1.mdx @@ -10,4 +10,12 @@ curl \ "primaryKey": "id" }' ``` + +```rust Rust +let client = Client::new("http://localhost:7700", Some("DEFAULT_ADMIN_API_KEY")); +let task = client + .create_index("medical_records", Some("id")) + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_basic_security_tutorial_listing_1.mdx b/snippets/samples/code_samples_basic_security_tutorial_listing_1.mdx index 549088f02..a9d2c5be0 100644 --- a/snippets/samples/code_samples_basic_security_tutorial_listing_1.mdx +++ b/snippets/samples/code_samples_basic_security_tutorial_listing_1.mdx @@ -4,4 +4,12 @@ curl -X GET 'MEILISEARCH_URL/keys' \ -H 'Authorization: Bearer MASTER_KEY' ``` + +```rust Rust +let client = Client::new("http://localhost:7700", Some("MASTER_KEY")); +client + .get_keys() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_basic_security_tutorial_search_1.mdx b/snippets/samples/code_samples_basic_security_tutorial_search_1.mdx index dbdade30f..edbef1caf 100644 --- a/snippets/samples/code_samples_basic_security_tutorial_search_1.mdx +++ b/snippets/samples/code_samples_basic_security_tutorial_search_1.mdx @@ -7,4 +7,15 @@ curl \ -H 'Authorization: Bearer DEFAULT_SEARCH_API_KEY' \ --data-binary '{ "q": "appointments" }' ``` + +```rust Rust +let client = Client::new("http://localhost:7700", Some("DEFAULT_SEARCH_API_KEY")); +let index = client.index("medical_records"); +index + .search() + .with_query("appointments") + .execute::() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_date_guide_filterable_attributes_1.mdx b/snippets/samples/code_samples_date_guide_filterable_attributes_1.mdx index 2fe51dc2b..98595a358 100644 --- a/snippets/samples/code_samples_date_guide_filterable_attributes_1.mdx +++ b/snippets/samples/code_samples_date_guide_filterable_attributes_1.mdx @@ -30,7 +30,7 @@ client.index('games').update_filterable_attributes(['release_timestamp']) ``` ```go Go -filterableAttributes := []string{"release_timestamp"} +filterableAttributes := []interface{}{"release_timestamp"} client.Index("games").UpdateFilterableAttributes(&filterableAttributes) ``` diff --git a/snippets/samples/code_samples_date_guide_index_1.mdx b/snippets/samples/code_samples_date_guide_index_1.mdx index 1f22bd3bd..4f89b156e 100644 --- a/snippets/samples/code_samples_date_guide_index_1.mdx +++ b/snippets/samples/code_samples_date_guide_index_1.mdx @@ -54,7 +54,7 @@ byteValue, _ := io.ReadAll(jsonFile) var games []map[string]interface{} json.Unmarshal(byteValue, &games) -client.Index("games").AddDocuments(games) +client.Index("games").AddDocuments(games, nil) ``` ```csharp C# diff --git a/snippets/samples/code_samples_distinct_attribute_guide_filterable_1.mdx b/snippets/samples/code_samples_distinct_attribute_guide_filterable_1.mdx index 60e30700b..7412dfadb 100644 --- a/snippets/samples/code_samples_distinct_attribute_guide_filterable_1.mdx +++ b/snippets/samples/code_samples_distinct_attribute_guide_filterable_1.mdx @@ -38,7 +38,7 @@ client.index('products').update_filterable_attributes([ ``` ```go Go -filterableAttributes := []string{ +filterableAttributes := []interface{}{ "product_id", "sku", "url", diff --git a/snippets/samples/code_samples_facet_search_1.mdx b/snippets/samples/code_samples_facet_search_1.mdx index dd2e10724..da8b4b9c9 100644 --- a/snippets/samples/code_samples_facet_search_1.mdx +++ b/snippets/samples/code_samples_facet_search_1.mdx @@ -60,6 +60,16 @@ var query = new SearchFacetsQuery() await client.Index("books").FacetSearchAsync("genres", query); ``` +```rust Rust +let res = client.index("books") + .facet_search("genres") + .with_facet_query("fiction") + .with_filter("rating > 3") + .execute() + .await + .unwrap(); +``` + ```dart Dart await client.index('books').facetSearch( FacetSearchQuery( diff --git a/snippets/samples/code_samples_facet_search_2.mdx b/snippets/samples/code_samples_facet_search_2.mdx index a5380a0ae..6f56f8435 100644 --- a/snippets/samples/code_samples_facet_search_2.mdx +++ b/snippets/samples/code_samples_facet_search_2.mdx @@ -62,6 +62,20 @@ var newFaceting = new Faceting await client.Index("books").UpdateFacetingAsync(newFaceting); ``` +```rust Rust +let mut facet_sort_setting = BTreeMap::new(); +facet_sort_setting.insert("genres".to_string(), FacetSortValue::Count); +let faceting = FacetingSettings { + max_values_per_facet: 100, + sort_facet_values_by: Some(facet_sort_setting), +}; + +let res = client.index("books") + .set_faceting(&faceting) + .await + .unwrap(); +``` + ```dart Dart await client.index('books').updateFaceting( Faceting( diff --git a/snippets/samples/code_samples_facet_search_3.mdx b/snippets/samples/code_samples_facet_search_3.mdx index e6fbb1894..70c2bcdc9 100644 --- a/snippets/samples/code_samples_facet_search_3.mdx +++ b/snippets/samples/code_samples_facet_search_3.mdx @@ -42,6 +42,7 @@ client.index('books').facet_search('genres', 'c') client.Index("books").FacetSearch(&meilisearch.FacetSearchRequest{ FacetQuery: "c", FacetName: "genres", + ExhaustiveFacetCount: true }) ``` @@ -53,6 +54,15 @@ var query = new SearchFacetsQuery() await client.Index("books").FacetSearchAsync("genres", query); ``` +```rust Rust +let res = client.index("books") + .facet_search("genres") + .with_facet_query("c") + .execute() + .await + .unwrap(); +``` + ```dart Dart await client.index('books').facetSearch( FacetSearchQuery( diff --git a/snippets/samples/code_samples_faceted_search_update_settings_1.mdx b/snippets/samples/code_samples_faceted_search_update_settings_1.mdx index 9c7b7d243..7b5255a44 100644 --- a/snippets/samples/code_samples_faceted_search_update_settings_1.mdx +++ b/snippets/samples/code_samples_faceted_search_update_settings_1.mdx @@ -34,7 +34,7 @@ client.index('movie_ratings').update_filterable_attributes(['genres', 'rating', ``` ```go Go -filterableAttributes := []string{ +filterableAttributes := []interface{}{ "genres", "rating", "language", diff --git a/snippets/samples/code_samples_filtering_update_settings_1.mdx b/snippets/samples/code_samples_filtering_update_settings_1.mdx index b73c1095b..9ecaed4cf 100644 --- a/snippets/samples/code_samples_filtering_update_settings_1.mdx +++ b/snippets/samples/code_samples_filtering_update_settings_1.mdx @@ -47,7 +47,7 @@ client.index('movies').update_filterable_attributes([ ``` ```go Go -resp, err := client.Index("movies").UpdateFilterableAttributes(&[]string{ +resp, err := client.Index("movies").UpdateFilterableAttributes(&[]interface{}{ "director", "genres", }) diff --git a/snippets/samples/code_samples_geosearch_guide_filter_settings_1.mdx b/snippets/samples/code_samples_geosearch_guide_filter_settings_1.mdx index 79aa98f98..32732e600 100644 --- a/snippets/samples/code_samples_geosearch_guide_filter_settings_1.mdx +++ b/snippets/samples/code_samples_geosearch_guide_filter_settings_1.mdx @@ -37,7 +37,7 @@ client.index('restaurants').update_filterable_attributes(['_geo']) ``` ```go Go -filterableAttributes := []string{ +filterableAttributes := []interface{}{ "_geo", } client.Index("restaurants").UpdateFilterableAttributes(&filterableAttributes) diff --git a/snippets/samples/code_samples_get_all_batches_1.mdx b/snippets/samples/code_samples_get_all_batches_1.mdx index bce94d986..403117765 100644 --- a/snippets/samples/code_samples_get_all_batches_1.mdx +++ b/snippets/samples/code_samples_get_all_batches_1.mdx @@ -20,4 +20,8 @@ $client->getBatches(); ```ruby Ruby client.batches ``` + +```go Go +client.GetBatches(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_get_batch_1.mdx b/snippets/samples/code_samples_get_batch_1.mdx index 7b9a8a94c..a7bc333b1 100644 --- a/snippets/samples/code_samples_get_batch_1.mdx +++ b/snippets/samples/code_samples_get_batch_1.mdx @@ -20,4 +20,8 @@ $client->getBatch(BATCH_UID); ```ruby Ruby client.batch(BATCH_UID) ``` + +```go Go +client.GetBatch(BATCH_UID); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_get_embedders_1.mdx b/snippets/samples/code_samples_get_embedders_1.mdx index d7deff5fc..96325ca5d 100644 --- a/snippets/samples/code_samples_get_embedders_1.mdx +++ b/snippets/samples/code_samples_get_embedders_1.mdx @@ -8,4 +8,8 @@ curl \ ```ruby Ruby client.index('INDEX_NAME').embedders ``` + +```rust Rust +let embedders = index.get_embedders().await.unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_get_facet_search_settings_1.mdx b/snippets/samples/code_samples_get_facet_search_settings_1.mdx index 8b2b15b7c..bfb04ecd9 100644 --- a/snippets/samples/code_samples_get_facet_search_settings_1.mdx +++ b/snippets/samples/code_samples_get_facet_search_settings_1.mdx @@ -24,4 +24,12 @@ client.index('INDEX_UID').facet_search_setting ```go Go client.Index("books").GetFacetSearch() ``` + +```rust Rust +let facet_search: bool = client + .index(INDEX_UID) + .get_facet_search() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_get_prefix_search_settings_1.mdx b/snippets/samples/code_samples_get_prefix_search_settings_1.mdx index 19b518df4..155d4eddb 100644 --- a/snippets/samples/code_samples_get_prefix_search_settings_1.mdx +++ b/snippets/samples/code_samples_get_prefix_search_settings_1.mdx @@ -24,4 +24,12 @@ client.index('INDEX_UID').prefix_search ```go Go client.Index("books").GetPrefixSearch() ``` + +```rust Rust +let prefix_search: PrefixSearchSettings = client + .index(INDEX_UID) + .get_prefix_search() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_get_similar_post_1.mdx b/snippets/samples/code_samples_get_similar_post_1.mdx index a84416895..534a02785 100644 --- a/snippets/samples/code_samples_get_similar_post_1.mdx +++ b/snippets/samples/code_samples_get_similar_post_1.mdx @@ -39,4 +39,12 @@ client.Index("INDEX_NAME").SearchSimilarDocuments(&meilisearch.SimilarDocumentQu Embedder: "default", }, resp) ``` + +```rust Rust +let results = index + .similar_search("TARGET_DOCUMENT_ID", "EMBEDDER_NAME") + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_getting_started_add_documents.mdx b/snippets/samples/code_samples_getting_started_add_documents.mdx index 9d1256878..9a2a53b20 100644 --- a/snippets/samples/code_samples_getting_started_add_documents.mdx +++ b/snippets/samples/code_samples_getting_started_add_documents.mdx @@ -140,7 +140,7 @@ func main() { var movies []map[string]interface{} json.Unmarshal(byteValue, &movies) - _, err := client.Index("movies").AddDocuments(movies) + _, err := client.Index("movies").AddDocuments(movies, nil) if err != nil { panic(err) } @@ -192,7 +192,7 @@ namespace Meilisearch_demo ```text Rust // In your .toml file: [dependencies] - meilisearch-sdk = "0.28.0" + meilisearch-sdk = "0.29.1" # futures: because we want to block on futures futures = "0.3" # serde: required if you are going to use documents diff --git a/snippets/samples/code_samples_getting_started_add_meteorites.mdx b/snippets/samples/code_samples_getting_started_add_meteorites.mdx index 90a4cf556..77373581e 100644 --- a/snippets/samples/code_samples_getting_started_add_meteorites.mdx +++ b/snippets/samples/code_samples_getting_started_add_meteorites.mdx @@ -60,7 +60,7 @@ byteValue, _ := io.ReadAll(jsonFile) var meteorites []map[string]interface{} json.Unmarshal(byteValue, &meteorites) -client.Index("meteorites").AddDocuments(meteorites) +client.Index("meteorites").AddDocuments(meteorites, nil) ``` ```csharp C# diff --git a/snippets/samples/code_samples_getting_started_faceting.mdx b/snippets/samples/code_samples_getting_started_faceting.mdx index ccc590264..2461cbd02 100644 --- a/snippets/samples/code_samples_getting_started_faceting.mdx +++ b/snippets/samples/code_samples_getting_started_faceting.mdx @@ -78,8 +78,11 @@ await client.Index("movies").UpdateFacetingAsync(faceting); ``` ```rust Rust +let mut facet_sort_setting = BTreeMap::new(); +facet_sort_setting.insert("*".to_string(), FacetSortValue::Count); let mut faceting = FacetingSettings { max_values_per_facet: 2, + sort_facet_values_by: Some(facet_sort_setting), }; let task: TaskInfo = client diff --git a/snippets/samples/code_samples_index_settings_tutorial_api_get_setting_1.mdx b/snippets/samples/code_samples_index_settings_tutorial_api_get_setting_1.mdx index 897990733..b971e33ec 100644 --- a/snippets/samples/code_samples_index_settings_tutorial_api_get_setting_1.mdx +++ b/snippets/samples/code_samples_index_settings_tutorial_api_get_setting_1.mdx @@ -4,4 +4,11 @@ curl \ -X GET 'MEILISEARCH_URL/indexes/INDEX_NAME/settings/searchable-attributes' ``` + +```rust Rust +let searchable_attributes: Vec = index + .get_searchable_attributes() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_index_settings_tutorial_api_put_setting_1.mdx b/snippets/samples/code_samples_index_settings_tutorial_api_put_setting_1.mdx index 66b6ffee9..f82116ae0 100644 --- a/snippets/samples/code_samples_index_settings_tutorial_api_put_setting_1.mdx +++ b/snippets/samples/code_samples_index_settings_tutorial_api_put_setting_1.mdx @@ -9,4 +9,11 @@ curl \ "overview" ]' ``` + +```rust Rust +let task = index + .set_searchable_attributes(["title", "overview"]) + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_index_settings_tutorial_api_task_1.mdx b/snippets/samples/code_samples_index_settings_tutorial_api_task_1.mdx index 84c80314e..2242766f4 100644 --- a/snippets/samples/code_samples_index_settings_tutorial_api_task_1.mdx +++ b/snippets/samples/code_samples_index_settings_tutorial_api_task_1.mdx @@ -4,4 +4,8 @@ curl \ -X GET 'MEILISEARCH_URL/tasks/TASK_UID' ``` + +```rust Rust +let task_status = index.get_task(&task).await.unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_landing_getting_started_1.mdx b/snippets/samples/code_samples_landing_getting_started_1.mdx index 49d15df9e..b353fed74 100644 --- a/snippets/samples/code_samples_landing_getting_started_1.mdx +++ b/snippets/samples/code_samples_landing_getting_started_1.mdx @@ -81,7 +81,7 @@ documents := []map[string]interface{}{ { "id": 5, "title": "Moana" }, { "id": 6, "title": "Philadelphia" }, } -client.Index("movies").AddDocuments(documents) +client.Index("movies").AddDocuments(documents, nil) ``` ```csharp C# diff --git a/snippets/samples/code_samples_negative_search_1.mdx b/snippets/samples/code_samples_negative_search_1.mdx index 213db2da5..d55e30b10 100644 --- a/snippets/samples/code_samples_negative_search_1.mdx +++ b/snippets/samples/code_samples_negative_search_1.mdx @@ -14,4 +14,12 @@ client.index('movies').search('-escape') ```php PHP $client->index('movies')->search('-escape'); ``` + +```rust Rust +let results = index.search() + .with_query("-escape") + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_negative_search_2.mdx b/snippets/samples/code_samples_negative_search_2.mdx index bd3146b38..f25dc2bba 100644 --- a/snippets/samples/code_samples_negative_search_2.mdx +++ b/snippets/samples/code_samples_negative_search_2.mdx @@ -14,4 +14,12 @@ client.index('movies').search('-"escape"') ```php PHP $client->index('movies')->search('-"escape"'); ``` + +```rust Rust +let results = index.search() + .with_query("-\"escape room\"") + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_primary_field_guide_add_document_primary_key.mdx b/snippets/samples/code_samples_primary_field_guide_add_document_primary_key.mdx index 1c30ac801..6d8ecc627 100644 --- a/snippets/samples/code_samples_primary_field_guide_add_document_primary_key.mdx +++ b/snippets/samples/code_samples_primary_field_guide_add_document_primary_key.mdx @@ -85,7 +85,8 @@ documents := []map[string]interface{}{ "price": 5.00, }, } -client.Index("books").AddDocuments(documents, "reference_number") +refrenceNumber := "reference_number" +client.Index("books").AddDocuments(documents, &refrenceNumber) ``` ```csharp C# diff --git a/snippets/samples/code_samples_related_results_embedder_1.mdx b/snippets/samples/code_samples_related_results_embedder_1.mdx index 5a66c2737..1f285b42d 100644 --- a/snippets/samples/code_samples_related_results_embedder_1.mdx +++ b/snippets/samples/code_samples_related_results_embedder_1.mdx @@ -15,4 +15,20 @@ curl -X PATCH 'MEILISEARCH_URL/indexes/movies/settings' } }' ``` + +```rust Rust +let embedders = HashMap::from([( + String::from("movies-text"), + Embedder { + source: EmbedderSource::OpenAi, + api_key: Some(String::from("OPENAI_API_KEY")), + model: Some(String::from("text-embedding-3-small")), + document_template: Some(String::from("A movie titled '{{doc.title}}' released in {{ doc.release_date }}. The movie genres are: {{doc.genres}}. The story is about: {{doc.overview|truncatewords: 20}}")), + ..Embedder::default() + } +)]); +movies.set_embedders(&embedders) + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_related_results_search_1.mdx b/snippets/samples/code_samples_related_results_search_1.mdx index c2ae498ed..38bb44ab5 100644 --- a/snippets/samples/code_samples_related_results_search_1.mdx +++ b/snippets/samples/code_samples_related_results_search_1.mdx @@ -11,4 +11,13 @@ curl -X POST 'MEILISEARCH_URL/indexes/INDEX_NAME/search' \ } }' ``` + +```rust Rust +let results = movies.search() + .with_query("batman") + .with_hybrid("EMBEDDER_NAME", 0.5) + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_related_results_similar_1.mdx b/snippets/samples/code_samples_related_results_similar_1.mdx index 8e263858a..24fbdbf35 100644 --- a/snippets/samples/code_samples_related_results_similar_1.mdx +++ b/snippets/samples/code_samples_related_results_similar_1.mdx @@ -10,4 +10,11 @@ curl \ "embedder": "EMBEDDER_NAME" }' ``` + +```rust Rust +let results = movies.similar_search("192", "EMBEDDER_NAME") + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_reset_embedders_1.mdx b/snippets/samples/code_samples_reset_embedders_1.mdx index 77e8a2ff8..b9eaee801 100644 --- a/snippets/samples/code_samples_reset_embedders_1.mdx +++ b/snippets/samples/code_samples_reset_embedders_1.mdx @@ -8,4 +8,8 @@ curl \ ```ruby Ruby client.index('INDEX_NAME').reset_embedders ``` + +```rust Rust +index.reset_embedders().await.unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_reset_facet_search_settings_1.mdx b/snippets/samples/code_samples_reset_facet_search_settings_1.mdx index 6b939a3d3..9591211ce 100644 --- a/snippets/samples/code_samples_reset_facet_search_settings_1.mdx +++ b/snippets/samples/code_samples_reset_facet_search_settings_1.mdx @@ -24,4 +24,12 @@ client.index('INDEX_UID').reset_facet_search_setting ```go Go client.Index("books").ResetFacetSearch() ``` + +```rust Rust +let task: TaskInfo = client + .index(INDEX_UID) + .reset_facet_search() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_reset_prefix_search_settings_1.mdx b/snippets/samples/code_samples_reset_prefix_search_settings_1.mdx index a4670ca9c..b161e68b3 100644 --- a/snippets/samples/code_samples_reset_prefix_search_settings_1.mdx +++ b/snippets/samples/code_samples_reset_prefix_search_settings_1.mdx @@ -24,4 +24,12 @@ client.index('INDEX_UID').reset_prefix_search ```go Go client.Index("books").ResetPrefixSearch() ``` + +```rust Rust +let task: TaskInfo = client + .index(INDEX_UID) + .reset_prefix_search() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_search_parameter_guide_hybrid_1.mdx b/snippets/samples/code_samples_search_parameter_guide_hybrid_1.mdx index eb830e921..e61487848 100644 --- a/snippets/samples/code_samples_search_parameter_guide_hybrid_1.mdx +++ b/snippets/samples/code_samples_search_parameter_guide_hybrid_1.mdx @@ -29,4 +29,14 @@ $client->index('INDEX_NAME')->search('kitchen utensils', [ ] ]); ``` + +```rust Rust +let results = index + .search() + .with_query("kitchen utensils") + .with_hybrid("EMBEDDER_NAME", 0.9) + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_search_parameter_guide_vector_1.mdx b/snippets/samples/code_samples_search_parameter_guide_vector_1.mdx index 3c1c97152..ad8a2c35a 100644 --- a/snippets/samples/code_samples_search_parameter_guide_vector_1.mdx +++ b/snippets/samples/code_samples_search_parameter_guide_vector_1.mdx @@ -10,4 +10,14 @@ curl -X POST 'MEILISEARCH_URL/indexes/INDEX_NAME/search' \ } }' ``` + +```rust Rust +let results = index + .search() + .with_vector(&[0.0, 1.0, 2.0]) + .with_hybrid("EMBEDDER_NAME", 1.0) + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_search_parameter_reference_retrieve_vectors_1.mdx b/snippets/samples/code_samples_search_parameter_reference_retrieve_vectors_1.mdx index bb19be7a1..3aa36ee05 100644 --- a/snippets/samples/code_samples_search_parameter_reference_retrieve_vectors_1.mdx +++ b/snippets/samples/code_samples_search_parameter_reference_retrieve_vectors_1.mdx @@ -29,4 +29,15 @@ $client->index('INDEX_NAME')->search('kitchen utensils', [ ] ]); ``` + +```rust Rust +let results = index + .search() + .with_query("kitchen utensils") + .with_retrieve_vectors(true) + .with_hybrid("EMBEDDER_NAME", 0.5) + .execute() + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_search_post_1.mdx b/snippets/samples/code_samples_search_post_1.mdx index 3057177f4..dfb4452cb 100644 --- a/snippets/samples/code_samples_search_post_1.mdx +++ b/snippets/samples/code_samples_search_post_1.mdx @@ -39,7 +39,7 @@ await client.Index("movies").SearchAsync("American ninja"); let results: SearchResults = client .index("movies") .search() - .with_query("American ninja") + .with_query("american ninja") .execute() .await .unwrap(); diff --git a/snippets/samples/code_samples_typo_tolerance_guide_5.mdx b/snippets/samples/code_samples_typo_tolerance_guide_5.mdx index 6733ece79..55582c22b 100644 --- a/snippets/samples/code_samples_typo_tolerance_guide_5.mdx +++ b/snippets/samples/code_samples_typo_tolerance_guide_5.mdx @@ -26,4 +26,10 @@ $client->index('movies')->updateTypoTolerance([ 'disableOnNumbers' => true ]); ``` + +```go Go +client.Index("movies").UpdateTypoTolerance(&meilisearch.TypoTolerance{ + DisableOnNumbers: true +}) +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_update_embedders_1.mdx b/snippets/samples/code_samples_update_embedders_1.mdx index f8fb461ee..89c1458e1 100644 --- a/snippets/samples/code_samples_update_embedders_1.mdx +++ b/snippets/samples/code_samples_update_embedders_1.mdx @@ -46,4 +46,21 @@ client.index('INDEX_NAME').update_embedders( } ) ``` + +```rust Rust +let embedders = HashMap::from([( + String::from("default"), + Embedder { + source: EmbedderSource::OpenAi, + api_key: Some(String::from("OPEN_AI_API_KEY")), + model: Some(String::from("text-embedding-3-small")), + document_template: Some(String::from("A document titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}")), + ..Embedder::default() + } +)]); +let task = index + .set_embedders(&embedders) + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_update_facet_search_settings_1.mdx b/snippets/samples/code_samples_update_facet_search_settings_1.mdx index bb7a7ac19..bbcbe5a39 100644 --- a/snippets/samples/code_samples_update_facet_search_settings_1.mdx +++ b/snippets/samples/code_samples_update_facet_search_settings_1.mdx @@ -26,4 +26,12 @@ client.index('INDEX_UID').update_facet_search_setting(false) ```go Go client.Index("books").UpdateFacetSearch(false) ``` + +```rust Rust +let task: TaskInfo = client + .index(INDEX_UID) + .set_facet_search(false) + .await + .unwrap(); +``` \ No newline at end of file diff --git a/snippets/samples/code_samples_update_faceting_settings_1.mdx b/snippets/samples/code_samples_update_faceting_settings_1.mdx index b56548fe9..5c1ce28ef 100644 --- a/snippets/samples/code_samples_update_faceting_settings_1.mdx +++ b/snippets/samples/code_samples_update_faceting_settings_1.mdx @@ -85,8 +85,12 @@ await client.Index("books").UpdateFacetingAsync(faceting); ``` ```rust Rust +let mut facet_sort_setting = BTreeMap::new(); +facet_sort_setting.insert(String::from("*"), FacetSortValue::Alpha); +facet_sort_setting.insert(String::from("genres"), FacetSortValue::Count); let mut faceting = FacetingSettings { max_values_per_facet: 2, + sort_facet_values_by: Some(facet_sort_setting), }; let task: TaskInfo = client diff --git a/snippets/samples/code_samples_update_filterable_attributes_1.mdx b/snippets/samples/code_samples_update_filterable_attributes_1.mdx index e5319e8fe..280180ef9 100644 --- a/snippets/samples/code_samples_update_filterable_attributes_1.mdx +++ b/snippets/samples/code_samples_update_filterable_attributes_1.mdx @@ -71,9 +71,29 @@ client.index('movies').update_filterable_attributes([ ``` ```go Go -filterableAttributes := []string{ +filterableAttributes := []interface{}{ "genres", "director", + AttributeRule{ + AttributePatterns: []string{"tag"} + Features: AttributeFeatures{ + FacetSearch: false, + Filter: FilterFeatures{ + Equality: true, + Comparison: false, + } + } + }, + map[string]interface{}{ + "attributePatterns": []interface{}{"year"} + "features": map[string]interface{}{ + "facetSearch": false, + "filter": map[string]interface{}{ + "equality": true, + "comparison": true, + } + } + } } client.Index("movies").UpdateFilterableAttributes(&filterableAttributes) ``` diff --git a/snippets/samples/code_samples_update_prefix_search_settings_1.mdx b/snippets/samples/code_samples_update_prefix_search_settings_1.mdx index 2f7f00d6a..4e4dcd1f6 100644 --- a/snippets/samples/code_samples_update_prefix_search_settings_1.mdx +++ b/snippets/samples/code_samples_update_prefix_search_settings_1.mdx @@ -26,4 +26,12 @@ client.index('INDEX_UID').update_prefix_search('disabled') ```go Go client.Index("books").UpdatePrefixSearch("disabled") ``` + +```rust Rust +let task: TaskInfo = client + .index(INDEX_UID) + .set_prefix_search(PrefixSearchSettings::Disabled) + .await + .unwrap(); +``` \ No newline at end of file