StackTraces
Meilisearch已驗證

Meilisearch primary key 自動推斷失敗報 index_primary_key_no_candidate_found

@debug_master9 天前更新閱讀 6 min00

添加文檔時 Meilisearch 報 index_primary_key_no_candidate_found 或 index_primary_key_multiple_candidates_found,根因是未顯式指定 primaryKey 且文檔中找不到唯一以 id 結尾的字段。解法是在 POST 文檔時傳 ?primaryKey=字段名,或創建索引時設 primaryKey 參數。適用 Meilisearch 全版本。

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

  • 業務場景:往一個新建索引 POST 文檔,API 返回 taskUid,但輪詢任務狀態發現是 failed,錯誤碼是 index_primary_key_no_candidate_found。或者文檔裡同時有 id 和 author_id 兩個字段,報 index_primary_key_multiple_candidates_found。
  • 環境:Meilisearch v1.54.3,curl / 任意 SDK。
  • 關鍵區分:這不是文檔格式錯誤,也不是字段類型錯誤,是 Meilisearch 無法從文檔字段名中自動推斷出 primary key。

StackTrace(堆疊日誌)

場景一:文檔中沒有以 id 結尾的字段。官方文檔給出的完整錯誤響應:

{
    "uid": 1,
    "indexUid": "books",
    "status": "failed",
    "type": "documentAdditionOrUpdate",
    "canceledBy": null,
    "details": {
        "receivedDocuments": 5,
        "indexedDocuments": null
    },
    "error": {
        "message": "The primary key inference failed as the engine did not find any field ending with `id` in its name. Please specify the primary key manually using the `primaryKey` query parameter.",
        "code": "index_primary_key_no_candidate_found",
        "type": "invalid_request",
        "link": "https://docs.meilisearch.com/errors#index-primary-key-no-candidate-found"
    },
    "duration": "PT0.006579S",
    "enqueuedAt": "2026-10-02T10:19:14.464858Z",
    "startedAt": "2026-10-02T10:19:14.465369Z",
    "finishedAt": "2026-10-02T10:19:14.471948Z"
}

場景二:文檔中有多個以 id 結尾的字段(如 id 和 author_id):

{
    "uid": 4,
    "indexUid": "books",
    "status": "failed",
    "type": "documentAdditionOrUpdate",
    "canceledBy": null,
    "details": {
        "receivedDocuments": 5,
        "indexedDocuments": 5
    },
    "error": {
        "message": "The primary key inference failed as the engine found 2 fields ending with `id` in their names: 'id' and 'author_id'. Please specify the primary key manually using the `primaryKey` query parameter.",
        "code": "index_primary_key_multiple_candidates_found",
        "type": "invalid_request",
        "link": "https://docs.meilisearch.com/errors#index-primary-key-multiple-candidates-found"
    },
    "duration": "PT0.006002S",
    "enqueuedAt": "2026-10-02T10:44:42.625574Z",
    "startedAt": "2026-10-02T10:44:42.626041Z",
    "finishedAt": "2026-10-02T10:44:42.632043Z"
}

兩種情況下文檔都不會被索引,indexedDocuments 為 null 或 0。

Reproduce(復現程式碼)

場景一:文檔沒有以 id 結尾的字段:

curl -X POST 'http://localhost:7700/indexes/books/documents' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  --data-binary '[
    {"title": "Solaris", "author": "Stanislaw Lem", "isbn": "978-0156014000"},
    {"title": "Dune", "author": "Frank Herbert", "isbn": "978-0441013594"}
  ]'

# 返回 taskUid,但任务状态为 failed
# 文档字段:title, author, isbn —— 没有以 id 结尾的字段

場景二:文檔有多個以 id 結尾的字段:

curl -X POST 'http://localhost:7700/indexes/books/documents' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  --data-binary '[
    {"id": 1, "title": "Solaris", "author_id": 42},
    {"id": 2, "title": "Dune", "author_id": 43}
  ]'

# 字段:id, title, author_id —— 两个以 id 结尾,无法自动推断

Root Cause(根因分析)

自動推斷規則

Meilisearch 要求每個索引有一個 primary key——每個文檔中唯一標識自身的字段。如果創建索引時沒有顯式指定,Meilisearch 會嘗試從第一個文檔中自動推斷。官方文檔原文:

Suppose you add documents to an index without previously setting its primary key. In this case, Meilisearch will automatically look for an attribute ending with the string id in a case-insensitive manner (for example, uid, BookId, ID) in your first document and set it as the index’s primary key.

推斷邏輯是字段名以 id 結尾(不區分大小寫)。匹配的字段如 id、uid、movieId、product_id、ID 都可以作為候選。

兩種失敗場景

  1. 無候選:文檔中沒有任何以 id 結尾的字段(如只有 title、author、isbn)。Meilisearch 找不到候選,拋出 index_primary_key_no_candidate_found。
  2. 多候選:文檔中有多個以 id 結尾的字段(如 id 和 author_id)。Meilisearch 無法確定用哪個,拋出 index_primary_key_multiple_candidates_found。

兩種情況下文檔添加任務都會失敗,文檔不會被索引。這是有意為之——primary key 一旦設定且有文檔存在就不能更改,所以推斷不確定時寧可不索引。

推斷只看第一個文檔

Meilisearch 只檢查第一批文檔的第一個文檔物件來確定 primary key。如果第一個文檔有 id 字段但後續文檔缺少該字段,會報另一個錯誤 missing_document_id,而不是推斷失敗。

The Fix(解決方案)

方式一:POST 文檔時傳 primaryKey 查詢參數(最快)

curl -X POST 'http://localhost:7700/indexes/books/documents?primaryKey=isbn' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  --data-binary '[
    {"title": "Solaris", "author": "Stanislaw Lem", "isbn": "978-0156014000"}
  ]'

primaryKey 參數只在索引為空(首次添加文檔)時生效。如果索引已有 primary key,傳這個參數不會改變它。

方式二:創建索引時顯式指定 primaryKey

curl -X POST 'http://localhost:7700/indexes' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  --data-binary '{
    "uid": "books",
    "primaryKey": "isbn"
  }'

# 返回 taskUid,等待 task succeeded 后再添加文档

方式三:已有索引用 PATCH 修改 primaryKey

curl -X PATCH 'http://localhost:7700/indexes/books' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer aSampleMasterKey' \
  --data-binary '{"primaryKey": "isbn"}'

注意:primary key 一旦設置且索引中有文檔,不能直接更改。必須先刪除所有文檔,再修改 primary key,再重新添加。

注意事項

  • primary key 值只能是整數或字符串,字符串只能含字母數字(a-z A-Z 0-9)、連字符(-)和下劃線(_)。
  • 同一索引內 primary key 值必須唯一,重複值會覆蓋之前的文檔。
  • 最佳實踐:創建索引時就指定 primaryKey,不依賴自動推斷,避免首批文檔格式不統一導致的推斷失敗。

References(參考來源)

最後更新於 2026-10-02

這篇幫到你了嗎?

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

貢獻一條解法