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

这篇帮到你了吗?

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

贡献一条解法