Elasticsearch动态映射未自动转换字符串为数字问题咨询
首先直接给你结论:Elasticsearch不会自动把字符串格式的数字转换成映射里定义的数值类型,要么你提前在数据端转好,要么用ES的摄入管道(ingest pipeline)在ES内部做转换。
为啥你的设置没生效?
你可能以为动态模板或者字段映射会帮你自动转类型,但其实映射的作用只是定义字段该以什么类型存储和索引,它不负责转换输入数据的格式。
而且你提到检索后值还是字符串,大概率是第一次写入数据的时候,动态模板没触发(比如索引创建时模板没生效,或者首次写入时ES自动创建了字符串类型的字段)——一旦字段类型被自动创建后,就算你后来改了映射,也没法修改已有字段的类型了。
两种可行的解决办法
1. 提前转换数据(最推荐)
在把数据发给ES之前,手动把所有带Amount的字段从字符串转成数字,比如把 "freeAmount": "10" 改成 "freeAmount": 10。这种方式性能最好,也最直接,避免ES端额外的处理开销。
2. 用Ingest Pipeline在ES内部转换
如果没法在数据端改,那可以在ES里创建一个摄入管道,自动把字符串转成整数。举个例子:
先创建管道:
PUT _ingest/pipeline/convert_amount_fields { "description": "把所有*Amount结尾的字符串转成整数", "processors": [ { "convert": { "field": "*Amount", "type": "integer", "ignore_missing": true } } ] }
然后写入数据的时候指定用这个管道:
PUT your_index_name/_doc/1?pipeline=convert_amount_fields { "freeAmount": "10", "totalAmount": "60" }
注意:这个通配符
*Amount的匹配需要ES 7.10及以上版本支持,如果你的版本更低,就得逐个字段写convert处理器。
额外要注意的点
如果你的索引里已经存在错误类型的字段(比如freeAmount已经是字符串类型了),那你得先删掉这个索引,重新创建带正确映射的索引,再写入转换后的数据——ES不允许修改已有字段的类型。
另外再检查下你的动态模板:match: "*Amount"是匹配字段名结尾为Amount的字段,你的freeAmount和totalAmount都是符合的,这块逻辑没问题。
内容的提问来源于stack exchange,提问作者V-K

