StackTraces
Meilisearch已验证

Meilisearch 升级到 v1.15+ 后中文搜不到(需重建索引)

@debug_master6 天前更新阅读 6 min00

从 v1.15 之前的版本升级上来、索引里本来就存着中文数据的话,升级后如果不重建索引(reindex),中文查询和中文文档会被无视——搜索命中为空或明显偏少,也不报错。原因不是升级坏了,是 v1.15 换了 Charabia 的中文分词策略,旧索引里的 token 还是旧版本切出来的,跟新查询对不上。触发一次 reindex 就恢复。这条只对「从 v1.15 之前升级上来、库里已有中文」的实例成立;全新安装 v1.54.3 中文开箱可用,没有这个问题。

Issue & Env(案发现场与环境)

  • 触发场景:实例原本跑在 v1.15 之前的版本(如 v1.14 及更早),索引里已有中文数据。用 dumpless upgrade 之类的方式升级到 v1.15+ 之后,之前能搜到的中文词突然搜不到,或者命中数量骤减。
  • 环境:Meilisearch v1.15 及以上(本文背景实例升级到 v1.54.3)。跟 master key、索引 uid、有没有加 filter 都无关。
  • 适用边界:只有「先有中文数据 → 再升级到 v1.15+」这一条路径会中招。全新空库、之后才灌中文文档的 v1.54.3 实例,中文分词是开箱就对的(本地实跑 v1.54.3,搜「三体」直接命中 id 1)。
  • 关键区分:它不是报错,没有 4xx,没有异常堆栈。搜索请求正常返回 200,只是结果不对——中文部分像是没进过索引。

StackTrace(堆栈日志)

这一条是官方说明型问题,没有报错文本。官方 v1.15 release notes 里的原文提示就是判断依据:

We’ve enhanced the Charabia tokenizer to provide more precise segmentation of Chinese text. If your dataset contains Chinese-language content, you must reindex your database. Otherwise, Chinese queries and documents will not be processed correctly and may be ignored during search.

(来源:Meilisearch 1.15 release notes)

对应的现象是搜索返回 200 但命中为空或偏少。比如重建前搜一个中文词,返回类似:

{
    "hits": [],
    "query": "三体",
    "processingTimeMs": 0,
    "limit": 20,
    "offset": 0,
    "estimatedTotalHits": 0
}

这里贴的是「中文被忽略」时 search 响应的形态(命中为空),不是报错 JSON——它不是错误,Meilisearch 不会为此返回错误码。要确认,请看下一节的判断方法。

Reproduce(复现步骤)

在升级后的实例上按顺序确认:

# 1. 确认当前版本 ≥ v1.15
curl -s http://localhost:7700/version \
  -H 'Authorization: Bearer aSampleMasterKey'

# 2. 搜一个库里的中文词,观察 estimatedTotalHits
curl -s -X POST http://localhost:7700/indexes/books_zh/search \
  -H 'Authorization: Bearer aSampleMasterKey' \
  -H 'Content-Type: application/json' \
  -d '{"q":"三体"}'

# 3. 查看该索引 localizedAttributes 是否为 null(未声明语言)
curl -s http://localhost:7700/indexes/books_zh/settings/localized-attributes \
  -H 'Authorization: Bearer aSampleMasterKey'

如果版本 ≥ v1.15、数据在升级前就存在、中文词命中为空或偏少,基本可以判定是旧索引没重建。

Root Cause(根因分析)

v1.15 换了中文分词策略

Meilisearch 的分词由 Charabia 负责。v1.15 增强了它对中文的切分精度(对应 GitHub release 里更新 charabia 的动作)。分词结果在索引阶段就写进了倒排索引——文档里的每个 token、它的位置信息都落盘了。

旧索引里的 token 是旧分词器切的

升级 Meilisearch 二进制不会自动重切已经索引好的文档。旧索引里存的是老版本 Charabia 切出来的中文 token;升级后查询侧用的是新版本分词逻辑,两边对不上,中文部分自然匹配不到。这不是数据丢了,是索引里的 token 过期了。

什么时候必须重建

官方给的判定很直接:只要数据集含中文内容,升级到 v1.15 后就得重建索引。官方同时给出了三种「触发重建」的方式,任选其一即可(它们都是会重索引全部文档的设置变更):

  1. 把中文 locale 加进 localizedAttributes(例如 cmn);
  2. 改动 stop words 或自定义 dictionary;
  3. 刷新 searchableAttributes——先把某个属性移出列表,等移除任务完成后再加回来。

The Fix(解决方案)

方式一:加中文 locale 触发重建

curl -X PUT 'http://localhost:7700/indexes/books_zh/settings/localized-attributes' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  -H 'Content-Type: application/json' \
  -d '[{"locales":["cmn"],"attributePatterns":["*_zh"]}]'

返回 {"taskUid":...,"type":"settingsUpdate"},这是异步任务,会重建该索引全部文档。

方式二:改动 dictionary 或 stop words 触发重建

对 dictionary 或 stopWords 做一次实际变更(哪怕加一个词)同样会触发重索引:

curl -X PUT 'http://localhost:7700/indexes/books_zh/settings/dictionary' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  -H 'Content-Type: application/json' \
  -d '["未来科技"]'

方式三:dump 恢复

用 dump 导出再导入到新版本,也能在建索引时用新分词器重建全部数据。官方把 dump 列为重建索引的推荐方式之一。

别忘了等任务完成

以上方式返回的都是 taskUid,要轮询到 succeeded 才算重建完:

curl -s http://localhost:7700/tasks/<taskUid> \
  -H 'Authorization: Bearer aSampleMasterKey'

任务跑完再搜,中文恢复命中。

边界提醒

  • 如果你是从 v1.15 之前升级上来的,重建一次就够,之后正常用。
  • 全新安装 v1.54.3、之后再灌中文数据的实例不需要做这些,中文本来就可用。
  • 重建会重新索引该索引的全部文档,数据量大时耗时较长,安排在低峰期做。

References(参考来源)

最后更新于 2026-10-05

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法