本页面旨在帮助 Algolia 的现有用户顺利过渡到 Meilisearch。

如需了解两家搜索公司及其产品的高层面对比,请参阅我们对搜索市场的分析

概述

本指南将逐步引导您创建一个 Node.js 脚本,用于将 Algolia 索引数据上传至 Meilisearch。您也可以直接跳转到完整脚本

迁移过程包含三个步骤:

  1. 导出 Algolia 中存储的数据
  2. 将数据导入 Meilisearch
  3. 配置 Meilisearch 索引设置(可选)

为便于过渡,我们还提供了 Meilisearch 与 Algolia 的 API 方法前端组件 对比。

继续之前,请确保已安装 Meilisearch 和 Node.js,并拥有命令行终端访问权限。如不确定如何安装 Meilisearch,请参阅我们的快速入门

本指南已在以下软件包版本中测试通过:

导出 Algolia 数据

初始化项目

首先创建目录 algolia-meilisearch-migration 并使用 npm 生成 package.json 文件:

mkdir algolia-meilisearch-migration
cd algolia-meilisearch-migration
npm init -y

这将设置安装依赖所需的环境。

接着创建 script.js 文件:

touch script.js

该文件将包含我们的迁移脚本。

安装依赖

首先需要安装两个不同的包。第一个是 algoliasearch,即 Algolia API 的 JavaScript 客户端;第二个是 meilisearch,即 Meilisearch API 的 JavaScript 客户端。

npm install -s algoliasearch@4.13 meilisearch@0.25.1

创建 Algolia 客户端

启动 Algolia 客户端需要您的 Application IDAdmin API Key。这两者都可以在您的 Algolia 账户 中找到。

将以下代码粘贴到 script.js 文件中:

const algoliaSearch = require("algoliasearch");

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

APPLICATION_IDADMIN_API_KEY 分别替换为您的 Algolia 应用 ID 和管理员 API 密钥。

INDEX_NAME 替换为您想要迁移到 Meilisearch 的 Algolia 索引名称。

从 Algolia 获取数据

要一次性获取 Algolia 索引中的所有数据,可以使用 Algolia 的 browseObjects 方法。

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

batch 回调方法会在每批数据命中时被调用,内容会被连接到 records 数组中。我们稍后在上传过程中还会再次使用 records

将数据导入 Meilisearch

创建 Meilisearch 客户端

通过传入您的 Meilisearch 实例的主机 URL 和 API 密钥来创建 Meilisearch 客户端。最简单的方法是使用自动生成的 admin API key

const { MeiliSearch } = require("meilisearch");

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

MEILI_HOSTMEILI_API_KEYMEILI_INDEX_NAME 替换为您的 Meilisearch 主机 URL、Meilisearch API 密钥以及您想要添加文档的索引名称。如果索引不存在,Meilisearch 会自动创建它。

上传数据到 Meilisearch

接下来,使用 Meilisearch JavaScript 方法 addDocumentsInBatches 以每批 100,000 条记录的方式上传所有数据。

const BATCH_SIZE = 100000;
await meiliIndex.addDocumentsInBatches(records, BATCH_SIZE);

这样就完成了!当您准备好运行脚本时,输入以下命令:

node script.js

完整脚本

const algoliaSearch = require("algoliasearch");
const { MeiliSearch } = require("meilisearch");

const BATCH_SIZE = 1000;

(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);
})();

配置索引设置

Meilisearch 的默认设置旨在为大多数使用场景提供快速且相关的搜索体验。

要自定义索引设置,我们建议遵循本指南。如需了解 Algolia 和 Meilisearch 在设置方面的差异,请继续阅读。

索引设置 vs. 搜索参数

Algolia 和 Meilisearch 的一个关键使用差异在于它们处理索引设置和搜索参数的方式。

在 Algolia 中,API 参数是一个灵活的类别,既包含索引设置也包含搜索参数。许多 API 参数既可以在索引时使用(设置默认行为),也可以在搜索时使用(覆盖该行为)。

在 Meilisearch 中,索引设置搜索参数是两个独立的类别。设置会影响索引上的所有搜索,而参数仅影响单次搜索结果。

某些 Meilisearch 参数需要预先配置索引设置。例如,必须先配置索引设置 sortableAttributes 才能使用搜索参数 sort。但与 Algolia 不同,索引设置永远不能作为参数使用,反之亦然。

设置与参数对比

下表将 Algolia 的 API 参数 与 Meilisearch 对应的 设置项搜索参数 进行对比。

AlgoliaMeilisearch
queryq
attributesToRetrieveattributesToRetrieve
filtersfilter
facetsfacetDistribution
attributesToHighlightattributesToHighlight
offsetoffset
lengthlimit
typoTolerancetypoTolerance
snippetEllipsisTextcropMarker
searchableAttributessearchableAttributes
attributesForFacetingfilterableAttributes
unretrievableAttributes无直接等效项;可通过从 displayedAttributes 中移除属性实现
attributesToRetrievedisplayedAttributes
attributeForDistinctdistinctAttribute
rankingrankingRules
customRanking已整合至 rankingRules
removeStopWordsstopWords
synonymssynonyms
排序(使用副本)sortableAttributes(无需副本)
removeWordsIfNoResults自动支持,但不可定制
disableTypoToleranceOnAttributestypoTolerance.disableOnAttributes
separatorsToIndex不支持
disablePrefixOnAttributes不支持
relevancyStrictness不支持
maxValuesPerFacetmaxValuesPerFacet
sortFacetValuesBysortFacetValuesBy
restrictHighlightAndSnippetArrays不支持

API 方法对比

本节使用 JavaScript 作为参考,比较 Algolia 和 Meilisearch 各自的 API 方法。

方法AlgoliaMeilisearch
索引实例化client.initIndex()
这里的 client 是 Algolia 实例
client.index()
这里的 client 是 Meilisearch 实例
创建索引Algolia 会在首次添加记录或设置时自动创建索引Meilisearch 同样适用,但用户也可以显式创建索引:client.createIndex(string indexName)
获取所有索引client.listIndices()client.getIndexes()
获取单个索引无可用方法client.getIndex(string indexName)
删除索引index.delete()client.deleteIndex(string indexName)
获取索引设置index.getSettings()index().getSettings()
更新索引设置index.setSettings(object settings)index().updateSettings(object settings)
搜索方法index.search(string query, { searchParameters, requestOptions })index.search(string query, object searchParameters)
添加对象index.saveObjects(array objects)index.addDocuments(array objects)
部分更新对象index.partialUpdateObjects(array objects)index.updateDocuments(array objects)
删除所有对象index.deleteObjects(array objectIDs)index.deleteAllDocuments()
删除单个对象index.deleteObject(string objectID)index.deleteDocument(string id)
获取所有对象index.getObjects(array objectIDs)index.getDocuments(object params)
获取单个对象index.getObject(str objectID)index.getDocument(string id)
获取 API 密钥client.listApiKeys()client.getKeys()
获取 API 密钥信息client.getApiKey(string apiKey)client.getKey(string apiKey)
创建 API 密钥client.addApiKey(array acl)client.createKey(object configuration)
更新 API 密钥client.updateApiKey(string apiKey, object configuration)client.updateKey(string apiKey, object configuration)
删除 API 密钥client.deleteApiKey(string apiKey)client.deleteKey(string apiKey)

前端组件

InstantSearch 是由 Algolia 维护的一套开源工具集,用于生成前端搜索界面组件。要在 Meilisearch 中使用 InstantSearch,您需要使用 Instant Meilisearch 插件。

Instant Meilisearch 是一个连接您的 Meilisearch 实例与 InstantSearch 的插件,使您能够使用与 Algolia 用户相同的众多前端组件。您可以在 GitHub 项目的 README 文件中找到 Instant Meilisearch 支持的组件的最新列表。