我在个人的一个文档项目中增加了全文检索功能,用到了 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");