昨天同事觸發定時任務發現es相關服務報了一個序列化問題,
今天早上捕獲異常將異常堆棧全部打出來看,才發現是聚合的字段不是keyword類型的問題。
到kibbna命令行執行也是一樣的錯誤
使用 /_mapping查看索引的字段類型,才發現userUniqueid是text類型
如果用text執行聚合,還必須在字段名后面加上 userUniqueid.keyword才能聚合。
需要重新建索引,指定類型!
這里說說text和keyword的區別
Text
????????當一個字段是要被全文檢索時,比如 Email 內容、產品描述,這些字段應該使用 text 類型。設置 text 類型以后,字段內容會被分析,在生成倒排索引之前,字符串會被分析器分成一個個詞項。text類型的字段不用于排序,很少用于聚合。????????
注意事項
- 適用于全文檢索:如 match 查詢。
- 文本字段會被分詞。
- 默認情況下,會創建倒排索引。
- 自動映射器會為 Text 類型創建 Keyword 字段。
Keyword
????????Keyword 類型適用于不分詞的字段,如姓名、Id、數字等。如果數字類型不用于范圍查找,用 Keyword 的性能要高于數值類型。
注意事項
- Keyword 不會對文本分詞,會保留字段的原有屬性,包括大小寫等。
- Keyword 僅僅是字段類型,而不會對搜索詞產生任何影響。
- Keyword 一般用于需要精確查找的字段,或者聚合排序字段。
- Keyword 通常和 Term 搜索一起用。
- Keyword 字段的?
ignore_above
?參數代表其截斷長度,默認 256,如果超出長度,字段值會被忽略,而不是截斷,忽略指的是會忽略這個字段的索引,搜索不到,但數據還是存在的。
那怎么將text類型修改為keyword呢?es不提供單個修改索引字段類型的方法,只能先創建一個中間索引(mappings里字段類型為keyword),然后將原索引數據遷移到這個索引里,再將原索引刪除,創建一個新的原索引名的索引(注意mappings保持和中間索引一致),再將中間索引的數據遷移到新的索引里。刪除中間索引。
從text類型修改為keyword類型
1 創建中間索引
PUT /tmp_index
{ ?"mappings":{"properties": {"appendixUrl": {"type": "keyword","index": false,"ignore_above": 256},"createTime": {"type": "date"},"department": {"type": "keyword","ignore_above": 256},"doctorName": {"type": "keyword","ignore_above": 256},"firmId": {"type": "keyword","ignore_above": 256},"grantUniqueId": {"type": "keyword","ignore_above": 256},"hospitalNumber": {"type": "keyword","ignore_above": 256},"notifyStatus": {"type": "long"},"overdueSigned": {"type": "keyword","ignore_above": 256},"patientCardNum": {"type": "keyword","ignore_above": 256},"patientName": {"type": "keyword","ignore_above": 256},"practicePlace": {"type": "keyword","ignore_above": 256},"recipeInfo": {"type": "keyword","index": false,"ignore_above": 256},"refuseReason": {"type": "keyword","index": false,"ignore_above": 256},"selfAuthId": {"type": "keyword","ignore_above": 256},"signTime": {"type": "date"},"signedPdfUrl": {"type": "keyword","index": false,"ignore_above": 256},"stampLogId": {"type": "keyword","index": false,"ignore_above": 256},"status": {"type": "long"},"subject": {"type": "keyword","ignore_above": 256},"sysTag": {"type": "keyword","ignore_above": 256},"tag": {"type": "text","analyzer": "comma","fielddata": true},"uniqueid": {"type": "keyword","ignore_above": 256},"upDefault1": {"type": "keyword","ignore_above": 256},"upDefault2": {"type": "keyword","ignore_above": 256},"updateTime": {"type": "date"},"urid": {"type": "keyword","ignore_above": 256},"userUniqueid": {"type": "keyword","ignore_above": 256}}
}
}
但因為未指定setting還報錯
{"error" : {"root_cause" : [{"type" : "mapper_parsing_exception","reason" : "Failed to parse mapping [_doc]: analyzer [comma] has not been configured in mappings"}],"type" : "mapper_parsing_exception","reason" : "Failed to parse mapping [_doc]: analyzer [comma] has not been configured in mappings","caused_by" : {"type" : "illegal_argument_exception","reason" : "analyzer [comma] has not been configured in mappings"}},"status" : 400
}
需要將setting也指定
GET /索引名/_settings查看索引的setting
加上settings再創建索引
"settings" : {
? ? ? ? "analysis" : {
? ? ? ? ? "analyzer" : {
? ? ? ? ? ? "comma" : {
? ? ? ? ? ? ? "pattern" : ",",
? ? ? ? ? ? ? "type" : "pattern"
? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ?
2 遷移數據
POST _reindex?wait_for_completion=false
{"source": {"index": "源索引名"},"dest": {"index": "tmp_index"}
}
3 刪除源索引
DELETE 源索引名
4 重建相同名稱的源索引名索引
同步驟1的命令
5 遷移數據
同步驟2,將源和目標索引互換一下即可