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

這篇幫到你了嗎?

剛解決了一個棘手的報錯?花兩分鐘記錄下來,幫助下一個遇到同樣問題的開發者。

貢獻一條解法