一、問題背景
在使用 Elasticsearch 存儲較大字段數據時,出現如下異常:
ElasticsearchStatusException: Elasticsearch exception [type=illegal_argument_exception, reason=Document contains at least one immense term in field="fieldZgbpka" (whose UTF8 encoding is longer than the max length 32766)...
?
如下圖所示:
二、錯誤分析
這是 Elasticsearch 的一個安全機制:默認情況下,不允許索引超大字段內容(即 term 超過 32766 bytes)。Elasticsearch 會跳過這些字段的內容,同時拋出 illegal_argument_exception
。
常見觸發原因:
-
向索引中寫入了超長字符串,如大型 JSON、富文本、Base64 圖片等;
-
默認
text
類型字段被自動建立倒排索引。
?
三、解決方案:
設置 index: false
禁用字段索引
如果該字段不參與搜索,僅作存儲用途(比如附件內容、HTML、大文本、JSON 字符串等),可以將其設為不可索引,即:
"fieldZgbpka": {
? "type": "text",
? "index": false
}
四:解決步驟(我這個方案比較笨)
1.先查詢有那些索引
GET wk_single_pack/_mapping
?大概結果如下圖:
2.刪除舊索引
然后建立一個新的索引,對應的改成text 把索引禁用掉fase別的保持不變。
這是刪除原有索引的命令,看到true就成功了。
DELETE /wk_single_pack
3.建立新的索引
PUT wk_single_pack
{
? "mappings": {
? ? ? "_doc": {
? ? ? ? "properties": {
? ? ? ? ? "checkStatus": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "createTime": {
? ? ? ? ? ? "type": "date",
? ? ? ? ? ? "format": "yyyy-MM-dd HH:mm:ss"
? ? ? ? ? },
? ? ? ? ? "createUserId": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "createUserName": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "documentCode": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "fieldOouzhm": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "fieldZgbpka": {
? ? ? ? ? ? "type": "text",
? ? ? ? ? ? "index": false
? ? ? ? ? },
? ? ? ? ? "fieldZorzlq": {
? ? ? ? ? ? "type": "text",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "keyword": {
? ? ? ? ? ? ? ? "type": "keyword"
? ? ? ? ? ? ? },
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "orderNumber": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "ownerDeptId": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "ownerDeptName": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "ownerUserId": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "ownerUserName": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "salesman": {
? ? ? ? ? ? "type": "keyword",
? ? ? ? ? ? "fields": {
? ? ? ? ? ? ? "sort": {
? ? ? ? ? ? ? ? "type": "icu_collation_keyword",
? ? ? ? ? ? ? ? "language": "zh",
? ? ? ? ? ? ? ? "country": "CN"
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? },
? ? ? ? ? "totalAmount": {
? ? ? ? ? ? "type": "scaled_float",
? ? ? ? ? ? "scaling_factor": 100
? ? ? ? ? },
? ? ? ? ? "updateTime": {
? ? ? ? ? ? "type": "date",
? ? ? ? ? ? "format": "yyyy-MM-dd HH:mm:ss"
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
}如下圖,根據自己的實際情況來。
?
五、注意事項
-
避免存儲超大內容到默認 text 字段;
-
如果確實需要,可用
index: false
或改為keyword
; -
若需搜索大字段(如全文搜索),考慮引入專門的搜索字段(如摘要);
-
別忘了提前設計 Mapping,Elasticsearch 動態 Mapping 默認會索引所有字段。
六、總結
本次問題是由于字段內容超出 Elasticsearch 的最大 term 限制 32766 字節導致。解決方案二通過設置字段 index: false
,禁止其參與倒排索引,既解決了異常問題,又保留了數據的存儲功能。
在實際開發中,我們要對每個字段的數據結構與使用場景做好規劃,合理設計索引策略,避免不必要的性能浪費與錯誤。
?