Elasticsearch中32位float类型term查询异常问题咨询
问题解答
1. 2219658752的特殊性
32位float的精度瓶颈不在数值上限(它的上限约为3.4e38),而在于有效位数:它的尾数部分只有23位(加上隐含的1位共24位二进制有效数字),对应十进制大约是6-7位有效数字。
你提到的2219658785和2219658651都是10位整数,远超过float的有效位数范围。当把这两个数转成float时,会被舍入到最接近的可精确表示的float值,也就是2219658752。这是因为这两个数之间的差值(134)小于当前量级下float能区分的最小单位(即float的“ulp”,单位在最后一位有效数字上),所以float无法区分它们,只能映射到同一个值。
2. 能否用term查询精准匹配?
不行。因为原始的两个数值在索引时已经被转换为同一个float值(2219658752)存储,Elasticsearch的term查询是基于存储的精确值匹配的,所以无法区分这两个原始值。
解决这个问题的唯一可靠方案是重新索引数据,将cid字段的类型改为long或double:
- long是整数类型,可以精确存储所有小于9e18的整数,完全覆盖你的cid数值范围;
- double的有效位数约为15-17位十进制,也能精确存储这两个10位整数,不会出现精度丢失。
如果暂时无法重新索引,虽然可以尝试用script查询直接对比原始输入值和文档中的值,但这种方式性能极差,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者Jozef - Spatialized.io
相关产品推荐
相关产品推荐

