如何将Elasticsearch中execution_time_millis字段改为long类型?
解决execution_time_millis字段类型转为Long的问题
我来帮你搞定这个字段类型不匹配的问题哈~核心原因有两个:一是得确保Logstash真的把字段转成了数字类型,二是Elasticsearch的索引映射一旦固化就没法直接修改,得重新调整。
第一步:确保Logstash的类型转换真正生效
你的mutate配置逻辑没问题,但看你提供的原始日志,里面已经自带了字符串类型的execution_time_millis字段,这会和dissect提取的字段产生冲突,导致转换可能没生效。可以调整下filter的顺序:
filter { if "EXECUTION_TIME" in [tags] { # 先删掉原始的字符串字段,避免干扰后续解析 mutate { remove_field => ["execution_time_millis"] } dissect { mapping => { "message" => "%{endpoint} timeMillis:[%{execution_time_millis}] data:%{additional_data}" } } mutate { convert => { "execution_time_millis" => "integer" } } } }
修改完后启动Logstash,看stdout的输出,如果execution_time_millis变成了不带引号的数字(比如"execution_time_millis": 142),说明Logstash这边的转换已经成功了,接下来解决ES的映射问题。
第二步:修正Elasticsearch的索引映射
Elasticsearch的动态映射规则是:第一次检测到字段时就会固定它的类型。如果最开始这个字段被识别成了string,哪怕后续传的是数字,ES也会自动转成string来适配现有映射。解决办法有两种:
方案1:删除现有索引,重建并指定映射
- 先删掉已有的目标索引(比如你配置的
elk-2018):
curl -X DELETE "localhost:9200/elk-2018"
- 提前创建新索引,明确指定
execution_time_millis的类型为long:
curl -X PUT "localhost:9200/elk-2018" -H 'Content-Type: application/json' -d' { "mappings": { "log": { "properties": { "execution_time_millis": { "type": "long" }, // 可以顺便把其他需要固定类型的字段也加上,比如level_value "level_value": { "type": "integer" } } } } } '
- 重启Logstash重新导入日志,这时候字段就会被正确识别为long类型了。
方案2:创建索引模板(推荐,一劳永逸)
如果你的索引是按年份动态生成的(比如elk-2024),可以创建一个索引模板,让所有匹配elk-*的索引自动应用正确的映射:
curl -X PUT "localhost:9200/_template/elk-template" -H 'Content-Type: application/json' -d' { "index_patterns": ["elk-*"], "mappings": { "log": { "properties": { "execution_time_millis": { "type": "long" }, "level_value": { "type": "integer" }, "@timestamp": { "type": "date" } } } } } '
创建完模板后,删除现有索引重新导入数据,后续新生成的年份索引都会自动套用这个映射规则。
验证结果
数据导入完成后,你可以在Kibana的索引模式管理里查看execution_time_millis的类型,也可以通过ES API确认:
curl -X GET "localhost:9200/elk-2018/_mapping"
这样就能彻底解决字段类型不匹配的问题啦~
内容的提问来源于stack exchange,提问作者Timothy
相关产品推荐
相关产品推荐

