Elasticsearch 报 "No handler for type [keyword] declared on field" 错误怎么办?
该错误表示 ES 版本不认识 keyword 类型——keyword 是 ES 5.x 引入的,旧版本用 string + not_analyzed。升级集群或改写 mapping 即可解决。本文给出两种修法与版本对照。
这个错误说明你用的 Elasticsearch 版本太老(2.x 或更早),不认识 keyword 类型——keyword 是 ES 5.0 才引入的。解法二选一:升级 ES,或把 mapping 改回旧版语法。
原因对照
| ES 版本 | 字符串精确匹配类型写法 |
|---|---|
| 2.x 及更早 | "type": "string", "index": "not_analyzed" |
| 5.x/6.x | "type": "keyword" |
| 7.x+ | "type": "keyword"(无 string 类型) |
修法一:升级集群(推荐)
ES 2.x 早已停止维护,安全与性能都有问题。升级后 mapping 直接用 keyword。
修法二:改写 mapping 兼容旧版
{
"mappings": {
"properties": {
"hostname": { "type": "string", "index": "not_analyzed" }
}
}
}
注意连锁反应
- 改 mapping 只对新索引生效,存量索引要 reindex;
- 客户端代码/模板(如 Logstash、Filebeat 自带的索引模板)也要与集群版本匹配——Filebeat 新版配 ES 老版常触发这个错,换匹配版本的 Beat 或关闭其模板自动加载。
观测云对照
观测云日志服务是自研的列式存储引擎,不存在 mapping 类型与版本兼容问题——日志字段自动识别,全文检索与精确筛选开箱可用。
常见问题(FAQ)
Q:怎么确认集群版本? curl localhost:9200 返回 JSON 里的 version.number。
Q:text 和 keyword 能同时用吗? 5.x+ 可以:主类型 text 用于全文,子字段 .keyword 用于精确匹配与聚合。