POST /indexes/{uid}/facet-search做分面值自動補全時,如果facetName屬性不在索引filterableAttributes列表中(拼錯、大小寫不符或忘聲明),返回 HTTP 400,錯誤碼invalid_facet_search_facet_name;facetName參數整個缺失則報missing_facet_search_facet_name。facet search 的前置條件是屬性必須可過濾。解法:把屬性聲明為 filterable 並等任務完成,再核對facetName與文檔字段完全一致。適用 Meilisearch 全版本。
Issue & Env(案發現場與環境)
- 業務場景:搜索頁面的分面下拉框需要自動補全,調用
POST /indexes/books/facet-search,body 傳{"facetName": "genres", "facetQuery": "fic"},返回 400。genres從未加入filterableAttributes;或把facetName拼成了"genre"(少了複數 s)。 - 環境:Meilisearch v1.54.3,curl / 任意 SDK 均可復現。
- 關鍵區分:這是 facet-search 端點特有的參數校驗錯誤,與主搜索端點的
invalid_search_filter是兩套錯誤碼;facetName缺失時走的是另一個錯誤碼missing_facet_search_facet_name。 - 典型觸發:前端分面下拉輸入框裡用戶輸入
fic觸發自動補全請求,接口 400 後下拉框沒有任何候選;或後端拼請求時facetName取值取到了undefined/拼寫錯誤,同樣踩中本文的錯誤碼。
StackTrace(堆疊日誌)
官方 Search for facet values API 文檔的前置條件原文:
Prerequisite: The
facetNameattribute must be in the index’sfilterableAttributeslist. Facet search will not work without this configuration.
錯誤碼參考頁對 invalid_facet_search_facet_name 的描述原文:
The attribute used for the
facetNamefield is either not a string or not defined in thefilterableAttributeslist.
官方規範(specs 0061)中該錯誤的響應結構(HTTP 400 同步返回,message 為運行期生成):
{
"message": "`:deserr_helper`",
"code": "invalid_facet_search_facet_name",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_facet_search_facet_name"
}
facetName 整個缺失時走 missing_facet_search_facet_name,錯誤碼參考頁描述原文:
The
facetNameparameter is required.
Reproduce(復現程式碼)
# 1. 索引 books 未声明任何 filterableAttributes(默认空数组)
# 2. 调用 facet-search——报 invalid_facet_search_facet_name
curl -X POST 'http://localhost:7700/indexes/books/facet-search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer aSampleMasterKey' \
--data-binary '{"facetName": "genres", "facetQuery": "fic"}'
# 返回 400: {"code": "invalid_facet_search_facet_name", "type": "invalid_request", ...}
# 3. 忘了传 facetName——报 missing_facet_search_facet_name
curl -X POST 'http://localhost:7700/indexes/books/facet-search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer aSampleMasterKey' \
--data-binary '{"facetQuery": "fic"}'
# 返回 400: {"code": "missing_facet_search_facet_name", "type": "invalid_request", ...}
Root Cause(根因分析)
facet-search 與 facets/filter 共用底層數據結構
facet-search 端點的設計前提:分面值統計依賴與 facets、filter 相同的內部數據結構,只有 filterableAttributes 裡的屬性才有分面值可供搜索。所以 API 文檔把“facetName 必須在 filterableAttributes”列為硬性前置條件(Prerequisite),不滿足就直接 400,不會像主搜索的 facets 參數那樣靜默忽略。
為什麼這裡報錯而不是靜默
主搜索端點的 facets 參數對未聲明屬性是靜默忽略(不報錯、只是不返回統計),但 facet-search 把 facetName 當作端點的核心輸入來做嚴格校驗:屬性沒有分面值可供搜索,整個端點就沒有意義,因此直接 400。排查時不能套用主搜索端點的“靜默忽略”經驗,兩個端點的容錯策略完全不同。
常見觸發原因
facetName與文檔字段名不完全一致:拼寫錯誤、大小寫不符(如Genres)、丟了嵌套前綴(如寫成language而字段是specs.language)。- 只聲明瞭搜索/展示用字段,忘了把分面字段加進
filterableAttributes。 - 設置了
filterableAttributes但沒等異步任務succeeded就調用——此時校驗仍失敗。 facetName傳了非字符串類型(如數字)也會觸發invalid_facet_search_facet_name。
容易混淆的相鄰問題
facetQuery只匹配第一個詞:搜Jane能命中Jane Austen,搜Austen則匹配不到——這是“能搜但搜不到”,不報錯,與本文的 400 無關。- 數值型分面值不可被 facet search 搜索,官方原文 “Numeric facet values are not searchable. Convert numbers to strings if you need to search them as facets.”——同樣不報錯,而是搜不到。
The Fix(解決方案)
第一步:把 facetName 屬性加入 filterableAttributes
curl -X PUT 'http://localhost:7700/indexes/books/settings/filterable-attributes' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer aSampleMasterKey' \
--data-binary '["genres", "rating", "language"]'
第二步:等設置任務完成
輪詢 GET /tasks/{taskUid} 直到 status: succeeded。設置更新會觸發該索引全量重建,耗時與數據量成正比。
第三步:重發 facet-search
curl -X POST 'http://localhost:7700/indexes/books/facet-search' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer aSampleMasterKey' \
--data-binary '{"facetName": "genres", "facetQuery": "fic"}'
# 返回: {"facetHits": [{"value": "Fiction", "count": 42}], "facetQuery": "fic", "processingTimeMs": 0}
排查順序建議
GET /indexes/{uid}/settings/filterable-attributes核對聲明列表裡有沒有該屬性。- 核對
facetName與文檔字段完全一致(大小寫、嵌套前綴)。 - 確認
facetName沒有被漏傳(漏傳報的是missing_facet_search_facet_name)。 - 其它參數校驗兜底:
facetQuery應為 string 或 null(報invalid_facet_search_query);exhaustiveFacetCount應為 boolean(報invalid_facet_search_exhaustive_facet_count)。 - 若確認屬性已聲明且拼寫無誤仍報錯,用
GET /indexes/{uid}/settings/facet-search檢查facetSearch索引設置是否被改成了false——該設置預設true,被關閉後調用會報facet_search_disabled(錯誤碼不同,別混淆)。
References(參考來源)
- Search for facet values API — Meilisearch 官方文檔meilisearch-docs
- Error codes — Meilisearch 官方文檔meilisearch-docs
- Error Format and Definitions — Meilisearch 規範文檔meilisearch-spec
