背景
1.用户在mapping中加一个字段 testid,结果写数据的时候使用 testId,同时也没有strict限制动态mapping,只是使用了默认的 true,即允许动态生成mapping
2.动态生成的字段 testId 被识别成了 float,用户为了方便,直接就使用了,没有重建索引或者加新字段
3. 用户的查询主要是精准查询,即terms
问题
用户查询的时候发现,terms里面明明没有这个id,但是查出来了这个文档;
查询结果:
testId 数组里面并没有 23780941 这个id存在,理论上不应该terms出来这个doc;
分析
1.字段类型为float,这个可能导致精度问题
"testId": {
"type": "float"
}
2.从kibana上看,并没有什么影响
3.kibana的UI展示丢精度的问题出现过,以往展示一个非常长的long类型时候,就会出现精度丢失的问题,为了看到ES返回的真实结果,我们直接curl命令行执行看看结果
4.查看结果,发现精度确实有问题,2.378094E7 表示 23780940,最后一位的精度丢失了,即1变成了0,所以 23780940 也可以查出来了
[2.378094E7,1.12870371E8,2.3646952E7,2.378094E7,1.12870371E8]
结论
1.使用float类型做term查询,很容易丢精度,且性能差,建议keyword
2.尽量不要使用动态mapping
3.如果设计到了float,或者非常长的 long,一定要注意kibana的UI展示精度问题