> ## Documentation Index
> Fetch the complete documentation index at: https://www.meilisearch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Algolia to Meilisearch

> This guide will take you step-by-step through the creation of a script to upload data indexed by Algolia to Meilisearch.

This page aims to help current users of Algolia make the transition to Meilisearch.

For a high-level comparison of the two search companies and their products, see [our analysis of the search market](/docs/resources/comparisons/alternatives#meilisearch-vs-algolia).

## Overview

This guide will take you step-by-step through the creation of a script to upload Algolia index data to Meilisearch. Examples are provided in JavaScript, Python, and Ruby. [You can also skip directly to the finished script](#finished-script).

The migration process consists of three steps:

1. [Export your data stored in Algolia](#export-your-algolia-data)
2. [Import your data into Meilisearch](#import-your-data-into-meilisearch)
3. [Configure your Meilisearch index settings (optional)](#configure-your-index-settings)

To help with the transition, we have also included a comparison of Meilisearch and Algolia's [API methods](#api-methods) and [front-end components](#front-end-components).

Before continuing, make sure you have Meilisearch installed and have access to a command-line terminal. If you're unsure how to install Meilisearch, see our [quick start](/docs/resources/self_hosting/getting_started/quick_start).

<Note>
  This guide includes examples in JavaScript, Python, and Ruby. The packages used:

  * **JavaScript**: [`algoliasearch`](https://www.npmjs.com/package/algoliasearch) `4.x`, [`meilisearch`](https://www.npmjs.com/package/meilisearch) (compatible with Meilisearch v1.0+)
  * **Python**: [`algoliasearch`](https://pypi.org/project/algoliasearch/) `4.x`, [`meilisearch`](https://pypi.org/project/meilisearch/)
  * **Ruby**: [`algolia`](https://rubygems.org/gems/algolia) `3.x`, [`meilisearch`](https://rubygems.org/gems/meilisearch)
</Note>

## Export your Algolia data

### Initialize project

<CodeGroup>
  ```bash JavaScript theme={null}
  mkdir algolia-meilisearch-migration
  cd algolia-meilisearch-migration
  npm init -y
  touch script.js
  ```

  ```bash Python theme={null}
  mkdir algolia-meilisearch-migration
  cd algolia-meilisearch-migration
  touch script.py
  ```

  ```bash Ruby theme={null}
  mkdir algolia-meilisearch-migration
  cd algolia-meilisearch-migration
  touch script.rb
  ```
</CodeGroup>

### Install dependencies

<CodeGroup>
  ```bash JavaScript theme={null}
  npm install -s algoliasearch@4 meilisearch
  ```

  ```bash Python theme={null}
  pip install algoliasearch meilisearch
  ```

  ```bash Ruby theme={null}
  gem install algolia meilisearch
  ```
</CodeGroup>

### Create Algolia client

You'll need your **Application ID** and **Admin API Key** to start the Algolia client. Both can be found in your [Algolia account](https://www.algolia.com/account/api-keys).

Paste the below code in your script file:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const algoliaSearch = require("algoliasearch");

  const algoliaClient = algoliaSearch(
    "APPLICATION_ID",
    "ADMIN_API_KEY"
  );
  const algoliaIndex = algoliaClient.initIndex("INDEX_NAME");
  ```

  ```python Python theme={null}
  from algoliasearch.search.client import SearchClientSync

  algolia_client = SearchClientSync("APPLICATION_ID", "ADMIN_API_KEY")
  ```

  ```ruby Ruby theme={null}
  require 'algolia'

  algolia_client = Algolia::SearchClient.create(
    'APPLICATION_ID',
    'ADMIN_API_KEY'
  )
  ```
</CodeGroup>

Replace `APPLICATION_ID` and `ADMIN_API_KEY` with your Algolia application ID and admin API key respectively.

Replace `INDEX_NAME` with the name of the Algolia index you would like to migrate to Meilisearch.

### Fetch data from Algolia

To fetch all Algolia index data at once, use Algolia's [`browseObjects`](https://www.algolia.com/doc/api-reference/api-methods/browse/) method.

<CodeGroup>
  ```javascript JavaScript theme={null}
  let records = [];
  await algoliaIndex.browseObjects({
      batch: (hits) => {
        records = records.concat(hits);
      }
    });
  ```

  ```python Python theme={null}
  records = []
  for hit in algolia_client.browse_objects(index_name="INDEX_NAME"):
      records.append(hit)
  ```

  ```ruby Ruby theme={null}
  records = []
  algolia_client.browse_objects('INDEX_NAME') do |hit|
    records << hit
  end
  ```
</CodeGroup>

The records array will contain all documents from your Algolia index. We will use `records` again later in the upload process.

## Import your data into Meilisearch

### Create Meilisearch client

Create a Meilisearch client by passing the host URL and API key of your Meilisearch instance. The easiest option is to use the automatically generated [admin API key](/docs/resources/self_hosting/security/basic_security).

<CodeGroup>
  ```javascript JavaScript theme={null}
  const { Meilisearch } = require("meilisearch");

  const meiliClient = new Meilisearch({
    host: "MEILI_HOST",
    apiKey: "MEILI_API_KEY",
  });
  const meiliIndex = meiliClient.index("MEILI_INDEX_NAME");
  ```

  ```python Python theme={null}
  import meilisearch

  meili_client = meilisearch.Client("MEILI_HOST", "MEILI_API_KEY")
  meili_index = meili_client.index("MEILI_INDEX_NAME")
  ```

  ```ruby Ruby theme={null}
  require 'meilisearch'

  meili_client = MeiliSearch::Client.new(
    'MEILI_HOST',
    'MEILI_API_KEY'
  )
  meili_index = meili_client.index('MEILI_INDEX_NAME')
  ```
</CodeGroup>

Replace `MEILI_HOST`,`MEILI_API_KEY`, and `MEILI_INDEX_NAME` with your Meilisearch host URL, Meilisearch API key, and the index name where you would like to add documents. Meilisearch will create the index if it doesn't already exist.

### Upload data to Meilisearch

Next, use `addDocumentsInBatches` to upload all your records in batches of 100,000.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const BATCH_SIZE = 100000;
  await meiliIndex.addDocumentsInBatches(records, BATCH_SIZE);
  ```

  ```python Python theme={null}
  BATCH_SIZE = 100000
  meili_index.add_documents_in_batches(records, batch_size=BATCH_SIZE)
  ```

  ```ruby Ruby theme={null}
  BATCH_SIZE = 100000
  meili_index.add_documents_in_batches(records, BATCH_SIZE)
  ```
</CodeGroup>

That's all! When you're ready to run the script, enter the below command:

<CodeGroup>
  ```bash JavaScript theme={null}
  node script.js
  ```

  ```bash Python theme={null}
  python script.py
  ```

  ```bash Ruby theme={null}
  ruby script.rb
  ```
</CodeGroup>

### Finished script

<CodeGroup>
  ```javascript JavaScript theme={null}
  const algoliaSearch = require("algoliasearch");
  const { Meilisearch } = require("meilisearch");

  const BATCH_SIZE = 100000;

  (async () => {
    const algoliaClient = algoliaSearch("APPLICATION_ID", "ADMIN_API_KEY");
    const algoliaIndex = algoliaClient.initIndex("INDEX_NAME");

    let records = [];
    await algoliaIndex.browseObjects({
      batch: (hits) => {
        records = records.concat(hits);
      }
    });

    const meiliClient = new Meilisearch({
      host: "MEILI_HOST",
      apiKey: "MEILI_API_KEY",
    });
    const meiliIndex = meiliClient.index("MEILI_INDEX_NAME");

    await meiliIndex.addDocumentsInBatches(records, BATCH_SIZE);
  })();
  ```

  ```python Python theme={null}
  from algoliasearch.search.client import SearchClientSync
  import meilisearch

  BATCH_SIZE = 100000

  # Fetch all documents from Algolia
  algolia_client = SearchClientSync("APPLICATION_ID", "ADMIN_API_KEY")

  records = []
  for hit in algolia_client.browse_objects(index_name="INDEX_NAME"):
      records.append(hit)

  print(f"Fetched {len(records)} documents from Algolia")

  # Upload to Meilisearch
  meili_client = meilisearch.Client("MEILI_HOST", "MEILI_API_KEY")
  meili_index = meili_client.index("MEILI_INDEX_NAME")

  meili_index.add_documents_in_batches(records, batch_size=BATCH_SIZE)
  print("Migration complete")
  ```

  ```ruby Ruby theme={null}
  require 'algolia'
  require 'meilisearch'

  BATCH_SIZE = 100000

  # Fetch all documents from Algolia
  algolia_client = Algolia::SearchClient.create(
    'APPLICATION_ID',
    'ADMIN_API_KEY'
  )

  records = []
  algolia_client.browse_objects('INDEX_NAME') do |hit|
    records << hit
  end

  puts "Fetched #{records.length} documents from Algolia"

  # Upload to Meilisearch
  meili_client = MeiliSearch::Client.new('MEILI_HOST', 'MEILI_API_KEY')
  meili_index = meili_client.index('MEILI_INDEX_NAME')

  meili_index.add_documents_in_batches(records, BATCH_SIZE)
  puts 'Migration complete'
  ```
</CodeGroup>

## Configure your index settings

Meilisearch's default settings are designed to deliver a fast and relevant search experience that works for most use-cases.

To customize your index settings, we recommend following [this guide](/docs/resources/internals/indexes#index-settings). To learn more about the differences between settings in Algolia and Meilisearch, read on.

### Index settings vs. search parameters

One of the key usage differences between Algolia and Meilisearch is how they approach index settings and search parameters.

**In Algolia,** [API parameters](https://www.algolia.com/doc/api-reference/api-parameters/) are a flexible category that includes both index settings and search parameters. Many API parameters can be used either at indexing time (to set default behavior) or at search time (to override that behavior).

**In Meilisearch,** [index settings](/docs/reference/api/settings/list-all-settings) and [search parameters](/docs/reference/api/search/search-with-post) are two distinct categories. Settings affect all searches on an index, while parameters affect the results of a single search.

Some Meilisearch parameters require index settings to be configured beforehand. For example, you must first configure the index setting `sortableAttributes` to use the search parameter `sort`. However, unlike in Algolia, an index setting can never be used as a parameter and vice versa.

### Settings and parameters comparison

The below table compares Algolia's **API parameters** with the equivalent Meilisearch **setting** or **search parameter**. The **Type** column indicates whether the Meilisearch equivalent is a search parameter (param), an index setting (setting), or both.

#### Query and pagination

| Algolia               | Meilisearch                                                            | Type    |
| :-------------------- | :--------------------------------------------------------------------- | :------ |
| `query`               | `q`                                                                    | param   |
| `offset`              | `offset`                                                               | param   |
| `length`              | `limit`                                                                | param   |
| `page`                | `page`                                                                 | param   |
| `hitsPerPage`         | `hitsPerPage`                                                          | param   |
| `paginatedHits` limit | [`pagination.maxTotalHits`](/docs/reference/api/settings/update-pagination) | setting |

#### Filtering and sorting

| Algolia                  | Meilisearch                                                                                                     | Type            |
| :----------------------- | :-------------------------------------------------------------------------------------------------------------- | :-------------- |
| `filters`                | `filter`                                                                                                        | param           |
| `facets`                 | `facets`                                                                                                        | param           |
| `attributesForFaceting`  | [`filterableAttributes`](/docs/reference/api/settings/update-filterableattributes)                                   | setting         |
| `maxValuesPerFacet`      | [`faceting.maxValuesPerFacet`](/docs/reference/api/settings/update-faceting)                                         | setting         |
| `sortFacetValuesBy`      | [`faceting.sortFacetValuesBy`](/docs/reference/api/settings/update-faceting)                                         | setting         |
| `maxFacetHits`           | [`facetSearch`](/docs/reference/api/settings/update-facetsearch)                                                     | setting         |
| Sorting (using replicas) | [`sortableAttributes`](/docs/reference/api/settings/update-sortableattributes) + `sort` param (no replicas required) | setting + param |
| `distinct`               | `distinct` (per-query) or [`distinctAttribute`](/docs/reference/api/settings/update-distinctattribute) (index-wide)  | param + setting |
| `attributeForDistinct`   | [`distinctAttribute`](/docs/reference/api/settings/update-distinctattribute)                                         | setting         |

#### Geo search

| Algolia                         | Meilisearch                                            | Type  |
| :------------------------------ | :----------------------------------------------------- | :---- |
| `aroundLatLng` / `aroundRadius` | `_geoRadius(lat, lng, radius)` in `filter`             | param |
| `insideBoundingBox`             | `_geoBoundingBox([lat, lng], [lat, lng])` in `filter`  | param |
| `insidePolygon`                 | `_geoPolygon([lat, lng], [lat, lng], ...)` in `filter` | param |
| `aroundPrecision`               | No direct equivalent                                   | N/A   |

#### Highlighting and snippets

| Algolia                             | Meilisearch                       | Type  |
| :---------------------------------- | :-------------------------------- | :---- |
| `attributesToHighlight`             | `attributesToHighlight`           | param |
| `highlightPreTag`                   | `highlightPreTag`                 | param |
| `highlightPostTag`                  | `highlightPostTag`                | param |
| `attributesToSnippet`               | `attributesToCrop` + `cropLength` | param |
| `snippetEllipsisText`               | `cropMarker`                      | param |
| `restrictHighlightAndSnippetArrays` | Not supported                     | N/A   |

#### Attributes and ranking

| Algolia                        | Meilisearch                                                                                                                            | Type    |
| :----------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- | :------ |
| `searchableAttributes`         | [`searchableAttributes`](/docs/reference/api/settings/update-searchableattributes)                                                          | setting |
| `restrictSearchableAttributes` | `attributesToSearchOn`                                                                                                                 | param   |
| `attributesToRetrieve`         | `attributesToRetrieve`                                                                                                                 | param   |
| `unretrievableAttributes`      | No direct equivalent; achieved by removing attributes from [`displayedAttributes`](/docs/reference/api/settings/update-displayedattributes) | setting |
| `ranking`                      | [`rankingRules`](/docs/reference/api/settings/update-rankingrules)                                                                          | setting |
| `customRanking`                | Integrated within [`rankingRules`](/docs/reference/api/settings/update-rankingrules)                                                        | setting |
| `getRankingInfo`               | `showRankingScore` / `showRankingScoreDetails`                                                                                         | param   |

#### Typo tolerance and language

| Algolia                            | Meilisearch                                                                                                                               | Type            |
| :--------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | :-------------- |
| `typoTolerance`                    | [`typoTolerance`](/docs/reference/api/settings/update-typotolerance)                                                                           | setting         |
| `disableTypoToleranceOnAttributes` | `typoTolerance.disableOnAttributes`                                                                                                       | setting         |
| `removeStopWords`                  | [`stopWords`](/docs/reference/api/settings/update-stopwords)                                                                                   | setting         |
| `synonyms`                         | [`synonyms`](/docs/reference/api/settings/update-synonyms)                                                                                     | setting         |
| `separatorsToIndex`                | [`separatorTokens`](/docs/reference/api/settings/get-separatortokens) / [`nonSeparatorTokens`](/docs/reference/api/settings/get-nonseparatortokens) | setting         |
| `naturalLanguages`                 | [`localizedAttributes`](/docs/reference/api/settings/update-localizedattributes) setting + `locales` param                                     | setting + param |
| `queryType` (prefix matching)      | [`prefixSearch`](/docs/reference/api/settings/update-prefixsearch)                                                                             | setting         |
| `removeWordsIfNoResults`           | Automatically supported via `matchingStrategy` param                                                                                      | param           |

#### AI and vector search

| Algolia             | Meilisearch                                                                      | Type            |
| :------------------ | :------------------------------------------------------------------------------- | :-------------- |
| NeuralSearch `mode` | `hybrid` param + [`embedders`](/docs/reference/api/settings/update-embedders) setting | setting + param |
| `enableReRanking`   | Integrated in `hybrid` search                                                    | param           |
| AI personalization  | `personalize`                                                                    | param           |

#### Other

| Algolia                        | Meilisearch                                                                | Type  |
| :----------------------------- | :------------------------------------------------------------------------- | :---- |
| `analytics` / `clickAnalytics` | Separate [Analytics API](/docs/capabilities/analytics/advanced/events_endpoint) | N/A   |
| `disablePrefixOnAttributes`    | Not supported                                                              | N/A   |
| `relevancyStrictness`          | `rankingScoreThreshold`                                                    | param |

## API methods

This section compares Algolia and Meilisearch's respective API methods, using JavaScript for reference.

| Method                | Algolia                                                                             | Meilisearch                                                                                                            |
| :-------------------- | :---------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------- |
| Index Instantiation   | `client.initIndex()`<br />Here, client is an Algolia instance.                      | `client.index()`<br />Here, client is a Meilisearch instance.                                                          |
| Create Index          | Algolia automatically creates an index the first time you add a record or settings. | The same applies to Meilisearch, but users can also create an index explicitly: `client.createIndex(string indexName)` |
| Get All Indexes       | `client.listIndices()`                                                              | `client.getIndexes()`                                                                                                  |
| Get Single Index      | No method available                                                                 | `client.getIndex(string indexName)`                                                                                    |
| Delete Index          | `index.delete()`                                                                    | `client.deleteIndex(string indexName)`                                                                                 |
| Get Index Settings    | `index.getSettings()`                                                               | `index.getSettings()`                                                                                                  |
| Update Index Settings | `index.setSettings(object settings)`                                                | `index.updateSettings(object settings)`                                                                                |
| Search Method         | `index.search(string query, { searchParameters, requestOptions })`                  | `index.search(string query, object searchParameters)`                                                                  |
| Add Object            | `index.saveObjects(array objects)`                                                  | `index.addDocuments(array objects)`                                                                                    |
| Partial Update Object | `index.partialUpdateObjects(array objects)`                                         | `index.updateDocuments(array objects)`                                                                                 |
| Delete All Objects    | `index.deleteObjects(array objectIDs)`                                              | `index.deleteAllDocuments()`                                                                                           |
| Delete One Object     | `index.deleteObject(string objectID)`                                               | `index.deleteDocument(string id)`                                                                                      |
| Get All Objects       | `index.getObjects(array objectIDs)`                                                 | `index.getDocuments(object params)`                                                                                    |
| Get Single Object     | `index.getObject(str objectID)`                                                     | `index.getDocument(string id)`                                                                                         |
| Get API Keys          | `client.listApiKeys()`                                                              | `client.getKeys()`                                                                                                     |
| Get API Key Info      | `client.getApiKey(string apiKey)`                                                   | `client.getKey(string apiKey)`                                                                                         |
| Create API Key        | `client.addApiKey(array acl)`                                                       | `client.createKey(object configuration)`                                                                               |
| Update API Key        | `client.updateApiKey(string apiKey, object configuration)`                          | `client.updateKey(string apiKey, object configuration)`                                                                |
| Delete API Key        | `client.deleteApiKey(string apiKey)`                                                | `client.deleteKey(string apiKey)`                                                                                      |

## Front-end components

[InstantSearch](https://github.com/algolia/instantsearch.js) is a collection of open-source tools maintained by Algolia and used to generate front-end search UI components. To use InstantSearch with Meilisearch, you must use [Instant Meilisearch](https://github.com/meilisearch/meilisearch-js-plugins/tree/main/packages/instant-meilisearch).

Instant Meilisearch is a plugin connecting your Meilisearch instance with InstantSearch, giving you access to many of the same front-end components as Algolia users. You can find an up-to-date list of [the components supported by Instant Meilisearch](https://github.com/meilisearch/meilisearch-js-plugins/tree/main/packages/instant-meilisearch#-api-resources) in the GitHub project's README.
