Skip to content

v1.16: /export route #3315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: v1.16
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |-
Expand Down
3 changes: 2 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,8 @@
"reference/api/dump",
"reference/api/experimental_features",
"reference/api/metrics",
"reference/api/logs"
"reference/api/logs",
"reference/api/export"
]
},
{
Expand Down
64 changes: 64 additions & 0 deletions reference/api/export.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
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 instace 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

<RouteHighlighter method="POST" path="/export" />

Migrate data from the origin instance to a target instance.

### 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 full admin 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.

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 `false`, uses the index settings as configured in the origin instance. if `true`, uses the target instance settings. Optional, defaults to `false`.

### Example

<CodeSamplesExportPost1 />

#### Response

```json
{
"taskUid": 2,
"indexUid": null,
"status": "enqueued",
"type": "export",
"enqueuedAt": "2025-06-26T12:54:10.785864Z"
}
```
20 changes: 20 additions & 0 deletions reference/errors/error_codes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,26 @@ The [`offset`](/reference/api/documents#query-parameters) parameter is invalid.

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).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ await client.GetTasksAsync(new TasksQuery { Statuses = new List<TaskInfoStatus>
```rust Rust
let mut query = TasksQuery::new(&client);
let tasks = query
.with_statuses(["failed", "canceled"])
.with_statuses(["failed"])
.execute()
.await
.unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
</CodeGroup>
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
</CodeGroup>
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
</CodeGroup>
11 changes: 11 additions & 0 deletions snippets/samples/code_samples_basic_security_tutorial_search_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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::<MedicalRecord>()
.await
.unwrap();
```
</CodeGroup>
10 changes: 10 additions & 0 deletions snippets/samples/code_samples_facet_search_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
14 changes: 14 additions & 0 deletions snippets/samples/code_samples_facet_search_2.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
9 changes: 9 additions & 0 deletions snippets/samples/code_samples_facet_search_3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,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(
Expand Down
4 changes: 4 additions & 0 deletions snippets/samples/code_samples_get_all_batches_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ $client->getBatches();
```ruby Ruby
client.batches
```

```go Go
client.GetBatches();
```
</CodeGroup>
4 changes: 4 additions & 0 deletions snippets/samples/code_samples_get_batch_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ $client->getBatch(BATCH_UID);
```ruby Ruby
client.batch(BATCH_UID)
```

```go Go
client.GetBatch(BATCH_UID);
```
</CodeGroup>
4 changes: 4 additions & 0 deletions snippets/samples/code_samples_get_embedders_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ curl \
```ruby Ruby
client.index('INDEX_NAME').embedders
```

```rust Rust
let embedders = index.get_embedders().await.unwrap();
```
</CodeGroup>
8 changes: 8 additions & 0 deletions snippets/samples/code_samples_get_facet_search_settings_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
</CodeGroup>
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
</CodeGroup>
8 changes: 8 additions & 0 deletions snippets/samples/code_samples_get_similar_post_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
</CodeGroup>
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions snippets/samples/code_samples_getting_started_faceting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@
curl \
-X GET 'MEILISEARCH_URL/indexes/INDEX_NAME/settings/searchable-attributes'
```

```rust Rust
let searchable_attributes: Vec<String> = index
.get_searchable_attributes()
.await
.unwrap();
```
</CodeGroup>
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ curl \
"overview"
]'
```

```rust Rust
let task = index
.set_searchable_attributes(["title", "overview"])
.await
.unwrap();
```
</CodeGroup>
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
curl \
-X GET 'MEILISEARCH_URL/tasks/TASK_UID'
```

```rust Rust
let task_status = index.get_task(&task).await.unwrap();
```
</CodeGroup>
8 changes: 8 additions & 0 deletions snippets/samples/code_samples_negative_search_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```
</CodeGroup>
Loading