轻量级的搜索引擎 Meilisearch

1,367 阅读2分钟

我在个人的一个文档项目中增加了全文检索功能,用到了 Meiliseach,就把基本的使用记录下来。

Meilisearch 搜索引擎使用 Rust 语言开发,轻量,对中文搜索非常友好,几乎做到了零配置,零学习成本,部署即用,非常方便。

目前 Meilisearch 最新版本是 v0.30 (2022年12月6日)

使用 Docker 部署

docker run -it --rm \
    -p 7700:7700 \
    -e MEILI_MASTER_KEY='MASTER_KEY'\
    -v $(pwd)/meili_data:/meili_data \
    getmeili/meilisearch:v0.30 \
    meilisearch --env="development"

或者 docker-compose:

version: '3'
services:
  meilisearch:
    container_name: meilisearch
    image: getmeili/meilisearch:v0.30
    ports:
      - "7700:7700"
    environment:
      - MEILI_MASTER_KEY=MASTER_KEY
      - MEILI_ENV=development
    volumes:
      - /yourpath/meili_data:/meili_data

使用 MASTER_KEY 设定 Meilisearch 的连接密码。

使用 env 或者 MEILI_ENV 设置要部署的环境。如果是 development 环境,Meilisearch 提供了友好的 Web 界面,用于开发调试。production 环境下 Web 界面将被禁用。

Quick start

 1. 引入 Java SDK 依赖

官方提供了主流语言的 SDK,或者使用 HTTP 的方式访问 Meilisearch。我用的是 Java SDK。

<dependency>
  <groupId>com.meilisearch.sdk</groupId>
  <artifactId>meilisearch-java</artifactId>
  <version>0.8.0</version>
  <type>pom</type>
</dependency>

目前最新版 Java SDK 是 0.8.0,完全支持 Meilisearch v0.27.2 版本。如果是 Meilisearch v0.30 版本,检索文档时会报错。

 2. 添加文档

// 创建 Client
Client client = new Client(new Config("http://localhost:7700", "123456"));

// 创建索引(指定索引名:movies 和主键字段:id)
String indexUid = client.createIndex("movies", "id").getIndexUid();
Index index = client.index(indexUid);

List<Movie> movies = new ArrayList();
// 向索引中添加文档
index.addDocuments(JSONObject.toJSONString(movies));

先创建索引,再向索引添加文档。添加文档是以 JSON 格式发送,单条数据多条数据都可以,Meilisearch 会解析 JSON 来添加文档数据。

这里需要注意的是,在创建索引时,一定要手动指定哪个字段是文档的 Primary Key(主键),在更新或者删除文档时, Meilisearch 也是基于主键操作的。

初次使用,我因为没有手动指定哪个字段是主键,批量导入数据时,Meilisearch 把某个实际不是主键的字段作为主键,导致我有大量数据没有导入成功。最终查了文档,外加观察实际现象才发现,原来是没有设置主键的原因。

3. 检索文档

// 使用 SearchRequest 构建查询条件
SearchResult result = index.search(new SearchRequest(keyword)
                        .setMatches(true)
                        .setAttributesToHighlight(new String[]{"name", "content"});
// 返回 JSON 结果
String hits = result.getHits();

4. 更新文档

Index index = client.index("movies");
Movie movie = new Movie();
// 基于主键字段更新文档
index.updateDocuments(JSONObject.toJSONString(movie));

5. 删除文档

Index index = client.index("movies");
Movie movie = new Movie();
// 基于主键删除文档
index.deleteDocument(movie);

6. 删除索引下的全部文档

Index index = client.index("movies");
index.deleteAllDocuments();

7. 删除索引

client.deleteIndex("movies");

参考文档