feat:增加MeiliSearch文档

This commit is contained in:
2026-08-16 17:21:36 +08:00
parent 911429d591
commit a5569f70ae
2 changed files with 182 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
---
title: Meilisearch简介和使用
date: 2026-08-15
---
# 一、简介
  [Meilisearch](https://meilisearch.com.cn/docs/home) 是一个基于 Rust 构建的开源全文搜索引擎,面向“用户侧搜索体验”设计。通过 REST API 接收 JSON 文档并建立倒排索引,提供 sub50ms 的搜索响应、默认拼写容错、前缀搜索、相关度排序与过滤分面能力,适用于站内搜索、商品检索、文档/知识库搜索、Cmd+K、RAG 检索层等场景。
# 二、核心概念
| 概念 | 说明 |
|---|---|
| **Index索引** | 一组共享设置的文档集合,等价于“表”,如 `products``articles` |
| **Document文档** | JSON 对象,是搜索基本单位,必须包含主键 |
| **Primary Key主键** | 文档唯一标识,默认推断 `id`相同主键写入即覆盖upsert |
| **Task任务** | 所有写操作异步执行,返回 `taskUid`状态enqueued → processing → succeeded / failed |
| **Settings** | Index 级配置searchable / filterable / sortable / displayed attributes、ranking rules、synonyms、stop words、tokenizer |
| **Ranking Rules** | 默认相关度规则:`words → typo → proximity → attribute → sort → exactness`,可定制 |
| **Master Key** | 实例级最高密钥≥16 bytes用于生成其他 Key**禁止下发前端** |
| **API Key** | Search / Admin / Read-Only Admin / Chat按 action + index 粒度授权 |
| **Tenant Token** | 由 API Key 派生,搜索时注入 filter实现多租户行级隔离 |
| **Embedder** | 内建向量化配置,支持 OpenAI / HuggingFace / Ollama / Cohere / 自定义 REST用于 Hybrid Search |
# 三、与Elasticsearch比较
| 维度 | Meilisearch | Elasticsearch |
|---|---|---|
| 核心引擎 | Rust + LMDBmmap单机 ACID | Java + Apache Lucenedistributed |
| 部署形态 | 单进程 / 单容器 | 多节点集群shard + replica + 选主) |
| 查询延迟 | **sub-50ms 默认**(前缀/typo 开箱) | sub-100ms200ms需调优达到极低 P99 |
| 索引吞吐 | 中(异步 task 队列,单机受限) | 高bulk + 多 shard 并行) |
| 近实时性 | 亚秒级 task 完成即可见 | refresh_interval 默认 1s |
| 内存占用 | ~200MB 空闲,无 GC | 12GB+ 起JVM heap 调优关键 |
| 横向扩展 | 社区版单节点Cloud/企业版支持 shard+replica | 原生分片、副本、跨集群复制 |
| 规模上限 | 单机百万~千万文档(索引通常 < 100GB | PB 百亿~千亿文档 |
| 聚合分析 | facet 计数级 | 完整 aggregation / pipeline / SIEM |
| 分词/相关度 | 内置 Charabia + 默认 ranking | 显式 analyzer / DSL / fuzziness 调优 |
| 运维复杂度 | 启容器+key+dump | heap/shard/ILM/TLS/RBAC|
| 成本模型 | 单机 $1020/月级 | 托管最小集群 $150+/月级 |
| 许可证 | MIT CE / BUSL-1.1 | AGPL / SSPL / ELv2 |
# 四、Docker安装
```yml
services:
meilisearch:
image: getmeili/meilisearch:v1.16
container_name: meilisearch
restart: unless-stopped
ports:
- "7700:7700"
environment:
MEILI_MASTER_KEY: key
volumes:
- ./meili_data:/meili_data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7700/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
networks:
- meili-net
meilisearch-ui:
image: eyeix/meilisearch-ui:v0.15.1-lite
container_name: meilisearch-ui
restart: unless-stopped
ports:
- "24900:24900"
environment:
TZ: Asia/Shanghai
depends_on:
meilisearch:
condition: service_healthy
networks:
- meili-net
networks:
meili-net:
driver: bridge
```
&emsp;&emsp;启动后在浏览器中打开ip:24900新增实例和索引
# 五、SpringBoot集成
## 5.1 安装依赖
```xml
<dependency>
<groupId>com.meilisearch.sdk</groupId>
<artifactId>meilisearch-java</artifactId>
<version>0.20.0</version>
</dependency>
```
::: warning
该版本需要okhttp 4.12版本如有冲突需要指定okhttp版本
```xml
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
```
:::
## 5.2 配置属性
```yml
meilisearch:
host: http:/ip:7700
api-key: key
```
## 5.3 配置类
```java
@Configuration
@ConfigurationProperties(prefix = "meilisearch")
@Data
public class MeiliSearchConfig {
private String host;
private String apiKey;
@Bean
public Client meiliClient() {
return new Client(new Config(host, apiKey));
}
}
```
## 5.4 操作实例
```java
@Service
public class MeiliSearchServiceImpl implements MeiliSearchService {
@Resource
private Client meiliClient;
@Override
public <T> int addDocuments(String indexUid, List<T> documents) {
String jsonArray = JSONUtil.toJsonStr(documents);
TaskInfo taskInfo = meiliClient.index(indexUid).addDocuments(jsonArray);
meiliClient.waitForTask(taskInfo.getTaskUid());
return taskInfo.getTaskUid();
}
@Override
public void updateDocument(String indexUid, Object document) {
TaskInfo task = meiliClient.index(indexUid).updateDocuments(JSONUtil.toJsonStr(document));
meiliClient.waitForTask(task.getTaskUid());
}
@Override
public void deleteDocument(String indexUid, String documentId) {
TaskInfo task = meiliClient.index(indexUid).deleteDocument(documentId);
meiliClient.waitForTask(task.getTaskUid());
}
@Override
public SearchResult search(String indexUid, String query, List<String> highlightFields) {
SearchRequest request = new SearchRequest(query)
.setShowMatchesPosition(true)
.setAttributesToHighlight(highlightFields.toArray(new String[0]));
return (SearchResult) meiliClient.index(indexUid).search(request);
}
}
```
::: tip
这里如果开启高亮搜索会有个bug`Meilisearch ApiException: {Error=APIError: {message='Invalid value type at .attributesToHighlight: expected an array, but found a string: "**[Ljava.lang.String;@10fc5e2f**"', code='invalid_search_attributes_to_highlight', type='invalid_request',`
解决方案
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
```
参考[issue](https://github.com/meilisearch/meilisearch-java/issues/687)
:::