背景:

ES版本:6.3.2

对一个double类型字段进行sum求和时,出现丢失精度问题.

查出44条数据,求和结果为1004.9, 但是ES返回结果为1004.9000000000001

由于公司内部组件进行了封装,简单索引查询无需解析结果可直接供前端使用.所以不希望内存中重新解析,逐条处理数字,而是通过ES的功能直接实现保留2位小数.

于是开始全网搜索.

截止2021年11月29日21:19:42 的方案:

索引中的数字插入时*100, 取出时 / 100

每个条明细 / 100

GET /_search
    "query" : {
        "match_all": {}
    "script_fields" : {
        "test1" : {
            "script" : {
                "lang": "painless",
                "inline": "doc['qty'].value / 100"
        "test2" : {
            "script" : {
                "lang": "painless",
                "inline": "doc['qty'].value / factor",
                "params" : {
                    "factor"  : 100

sum结果 / 100

GET /_search
  "query" : {
        "match_all": {}
  "aggs": {
    "qty_name": {
      "sum": {
        "field": "qty",
        "script":"(doc['qty'].value) / 100"

ES不支持直接对某一列字段加减乘除,需要借助painless 脚本语言中的 Script Fields 进行计算.

Script Fields 语法

在stackoverflow找到了相同的问题,但效果都不好.​​​​​​   stackoverflow同类问题https://stackoverflow.com/questions/36041812/how-to-round-up-double-to-2-decimal-point-elasticsearch#https://stackoverflow.com/questions/36041812/how-to-round-up-double-to-2-decimal-point-elasticsearch#

stackoverflow中文翻译后的内容

 stackoverflow例子实测

ES索引如下:

"state": "open", "settings": { "index": { "creation_date": "1637576630382", "number_of_shards": "10", "number_of_replicas": "1", "uuid": "-----", "version": { "created": "6030299" "provided_name": "test_double" "mappings": { "_doc": { "dynamic": "false", "properties": { "qty": { "type": "double"

插入44条数据(从正式环境copy来的所以44条)

4.0 ,1.0 ,1.7 ,1.0 ,12.0 ,1.0 ,26.0 ,7.0 ,2.0 ,1.6 ,1.0 ,44.0 ,5.0 ,3.4 ,3.0 ,1.0 ,5.0 ,2.7 ,6.4 ,1.7 ,1.0 ,0.8 ,10.0 ,1.6 ,1.0 ,3.0 ,5.0 ,4.0 ,12.0 ,39.0 ,0.8 ,2.0 ,12.0 ,6.0 ,8.0 ,2.0 ,547.0 ,137.0 ,76.0 ,0.8 ,1.1 ,0.7 ,2.0 ,1.6 

普通求和:

math_round 保留小数:

round(2)保留两位小数:. 查询报错. 后查明没有这个方法Lucene表达式语言-数字类型字段API-没有round()方法

BigDecimal保留两位小数:

 BigDecimal是将44条的值都做四舍五入后进行加和, 结果与真实sum值差异较大,不能使用.

综上所有测试得出, 暂时没有办法直接将结果保留两位小数,所以只能考虑换个方式,索引中的数字*100 进行sum,取出来时再除以100。

如果大家有更好的方法,同求分享。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

  • 浏览量 4074
  • 收藏 0
  • 0

所有评论(0)