ES 7.14使用Painless脚本执行SUM聚合结果不符合预期
Elasticsearch 7.14 sum聚合结果异常原因
核心问题根源
非预期结果是float类型的精度丢失导致的,和Painless脚本、sum聚合逻辑本身无关。
具体原因说明
- Elasticsearch中
float是32位单精度浮点数,仅能保留约6~7位十进制有效数字,当数值大于2^24(约1677万)时,连整数部分都无法精确存储,更无法精确存储带小数的大数值。 - 你写入的
prices.sumRetailPrice值为5250000000.2,属于超过10位的大数值,远超出float的精度上限,写入时已经在底层docValues中被近似为一个接近但不等的浮点数值。 - 你在查询命中结果中看到的
5.2500000002E9是_source中存储的你写入的原始文本解析值,而Painless脚本读取的是列式存储的docValues中的近似值,因此聚合计算时得到的是近似结果5.249999872E9。
解决方案
- 将
prices.sumRetailPrice的字段类型修改为double:64位双精度浮点数可保留15~17位十进制有效数字,足够覆盖你当前的数值量级,可大幅降低精度误差。 - 若为金融等对精度要求极高的场景,将字段类型修改为
scaled_float,设置合适的scaling_factor(例如存在1位小数就设为10),底层会以long类型存储整数,完全避免浮点精度丢失。 - 临时兼容方案:修改Painless脚本读取
_source中的原始值而非docValues,该方案性能极差,仅适合小数据量验证使用,不推荐生产环境落地。
内容的提问来源于stack exchange,提问作者VaZa
相关产品推荐
相关产品推荐

