StackTraces
Meilisearch已驗證

Meilisearch 自定義排名規則舊語法報 invalid_settings_ranking_rules

@debug_master5 天前更新閱讀 6 min00

設置自定義排名規則時沿用舊版函數式語法 asc(price) / desc(price),PUT /settings/ranking-rules 返回 HTTP 400,錯誤碼 invalid_settings_ranking_rules。該語法自 v0.22 起廢棄,現行寫法是 属性名:asc / 属性名:desc(如 "release_date:desc")。改成新語法即可,但注意 PUT 是全量覆蓋,要把預設 7 條規則一起帶上。適用 Meilisearch v0.22 之後的版本,本篇以 v1.54.3 實測。

Issue & Env(案發現場與環境)

  • 業務場景:想給搜索結果加一條常駐的“新品優先”規則,讓最新發行的書排前面。按網上舊教程寫 desc(release_date),放進 PUT /indexes/books_sort/settings/ranking-rules,直接返回 400 Bad Request,錯誤碼 invalid_settings_ranking_rules。換成 release_date:desc 後立即通過。
  • 環境:Meilisearch v1.54.3,curl 調用 REST API。
  • 關鍵區分:invalid_settings_ranking_rules 觸發條件是 ranking-rules 設置值非法,與 search 請求無關,也不是異步任務沒等完。最常見兩類:舊語法 asc()/desc(),以及保留關鍵字(_geoPoint 等 _geo 系列)。本篇只講第一類。
  • 典型觸發:項目從舊版 Meilisearch 升級,或照著 2022 年前的博客/SDK 示例寫排名規則。舊資料裡的 asc(price) 寫法在新版一律報錯。

StackTrace(堆疊日誌)

本地實測原文(索引 books_sort,規則陣列第 8 位即下標 [7] 處傳了 desc(release_date)):

{
  "message": "Invalid value at `[7]`: `desc(release_date)` ranking rule is invalid. Valid ranking rules are words, typo, sort, proximity, attribute, exactness and custom ranking rules.",
  "code": "invalid_settings_ranking_rules",
  "type": "invalid_request",
  "link": "https://docs.meilisearch.com/errors#invalid_settings_ranking_rules"
}

asc(release_date)、desc(rating) 同樣被拒,報錯原文一致,只有 [7] 處的規則字符串不同。以上均為 HTTP 400 同步返回,不走異步任務。

注意 message 裡列的合法規則是 words, typo, sort, proximity, attribute, exactness——它還停留在 v1.36 拆分前的舊名單(attribute 是舊名)。v1.54.3 實際預設規則是 7 條:words, typo, proximity, attributeRank, sort, wordPosition, exactness。別拿這行報錯原文當預設規則的完整清單,以 GET /indexes/{uid}/settings 實際返回為準。

Reproduce(復現程式碼)

# 1. 用旧语法 desc() 设置自定义排名规则——报错
curl -X PUT 'http://localhost:7700/indexes/books_sort/settings/ranking-rules' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  --data-binary '["words","typo","proximity","attributeRank","sort","wordPosition","exactness","desc(release_date)"]'

# 返回 400:
# {"message": "Invalid value at `[7]`: `desc(release_date)` ranking rule is invalid. ...", "code": "invalid_settings_ranking_rules", ...}

Root Cause(根因分析)

語法自 v0.22 起廢棄

Meilisearch 的自定義排名規則最早採用函數式寫法 asc(属性) / desc(属性)。v0.22 起官方把語法改成 属性名:asc / 属性名:desc,舊的函數式寫法進入廢棄流程,新版本解析器直接拒絕,返回 invalid_settings_ranking_rules。官方博客 What’s new in v0.22 記錄了這次變更,理由是與 sort 參數(一直是 属性:方向 格式)保持一致的表達。

報錯信息能定位到具體下標

Invalid value at [7]`` 中的 [7] 是規則陣列的下標:release_date:desc 放在預設 7 條之後,即陣列第 8 位(下標 7)。哪一條非法,報錯就指出哪一位,排查時直接看這個位置。

PUT 是全量覆蓋,不是追加

PUT /settings/ranking-rules 的語義是把整個規則陣列替換掉,漏帶預設規則會直接沖掉 words/exactness。本地實測:只傳 ["release_date:desc"] 後 GET /settings 返回的 rankingRules 只剩這一條,相關度排序完全失效。所以修復時要把預設 7 條一起寫進去。

設置更新是異步任務

設置變更返回 taskUid(type 為 settingsUpdate),並觸發該索引全量重建。任務還在 enqueued/processing 時搜索,新規則不生效,也不報錯——表現是“看起來沒排對”,和這裡的 400 是兩回事。

The Fix(解決方案)

第一步:改成新語法,並帶上預設規則

curl -X PUT 'http://localhost:7700/indexes/books_sort/settings/ranking-rules' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  --data-binary '["words","typo","proximity","attributeRank","sort","wordPosition","exactness","release_date:desc"]'

返回 taskUid,type 為 settingsUpdate。

第二步:等任務完成

輪詢 GET /tasks/{taskUid} 直到 status: succeeded,再搜索驗證。沒等完就搜,新規則不生效。

第三步:驗證常駐生效

不傳 sort 參數直接搜,新規則已生效。本地實測 q=刘慈欣(該書庫含《三體》2008 與《球狀閃電》2004),加了 release_date:desc 後《三體》排到《球狀閃電》前面。

恢復預設

curl -X DELETE 'http://localhost:7700/indexes/books_sort/settings/ranking-rules' \
  -H 'Authorization: Bearer aSampleMasterKey'

其他排查點

  • 先 GET /indexes/{uid}/settings 核對當前 rankingRules,別憑記憶改。預設 7 條以實際返回為準(v1.36 起為 attributeRank + wordPosition,舊文檔可能仍寫 6 條含 attribute)。
  • 自定義規則放鏈尾是“軟排序”(tiebreaker,相關度優先),放鏈首是“硬排序”(業務排序優先、犧牲相關度)。
  • invalid_settings_ranking_rules 的另一類觸發是保留關鍵字,如 _geoPoint(lat,lng):asc 用於地理距離排序,誤寫成 _geo:asc 之類也會報同一錯誤碼。

References(參考來源)

最後更新於 2026-10-06

這篇幫到你了嗎?

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

貢獻一條解法