【问题标题】:How do i get accurate sum in elasticsearch based on source hits?如何根据源命中在弹性搜索中获得准确的总和?
【发布时间】:2019-04-28 00:40:41
【问题描述】:

如何在 elasticsearch 中获得精确的总和聚合?前参考我目前正在使用elasticsearch 5.6,我的索引映射如下所示:

{
  "my-index":{
    "mappings":{
      "my-type":{
        "properties":{
          "id":{
            "type":"keyword"
          },
          "fieldA":{
            "type":"double"
          },
          "fieldB":{
            "type":"double"
          },
          "fieldC":{
            "type":"double"
          },
          "version":{
            "type":"long"
          }
        }
      }
    }
  }
}

生成的搜索查询(使用 java 客户端)是:

{
 /// ... some filters here
 "aggregations" : {
       "fieldA" : {
         "sum" : {
           "field" : "fieldA"
         }
       },
       "fieldB" : {
         "sum" : {
           "field" : "fieldB"
         }
       },
       "fieldC" : {
         "sum" : {
           "field" : "fieldC"
         }
       }
     }
}

但是,我的结果命中会生成以下内容:

{
    "took": 10,
    "timed_out": false,
    "_shards": {
        "total": 3,
        "successful": 3,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 5,
        "max_score": 3.8466966,
        "hits": [
            {
                "_index": "my-index",
                "_type": "my-type",
                "_id": "25a203b63e264fd2be13db006684b06d",
                "_score": 3.8466966,
                "_source": {
                    "fieldC": 108,
                    "fieldA": 108,
                    "fieldB": 0
                }
            },
            {
                "_index": "my-index",
                "_type": "my-type",
                "_id": "25a203b63e264fd2be13db006684b06d",
                "_score": 3.8466966,
                "_source": {
                    "fieldC": -36,
                    "fieldA": 108,
                    "fieldB": 144
                }
            },
            {
                "_index": "my-index",
                "_type": "my-type",
                "_id": "25a203b63e264fd2be13db006684b06d",
                "_score": 3.8466966,
                "_source": {
                    "fieldC": -7.2,
                    "fieldA": 1.8,
                    "fieldB": 9
                }
            },
            {
                "_index": "my-index",
                "_type": "my-type",
                "_id": "25a203b63e264fd2be13db006684b06d",
                "_score": 3.8466966,
                "_source": {
                    "fieldC": 14.85,
                    "fieldA": 18.9,
                    "fieldB": 4.05
                }
            },
            {
                "_index": "my-index",
                "_type": "my-type",
                "_id": "25a203b63e264fd2be13db006684b06d",
                "_score": 3.8466966,
                "_source": {
                    "fieldC": 36,
                    "fieldA": 36,
                    "fieldB": 0
                }
            }
        ]
    },
    "aggregations": {
        "fieldA": {
            "value": 272.70000000000005
        },
        "fieldB": {
            "value": 157.05
        },
        "fieldC": {
            "value": 115.64999999999999
        }
    }
}

我为什么会得到:

115.64999999999999 而不是 fieldC 中的 115.65 272.70000000000005 而不是 fieldA 中的 272.7

我应该使用浮点数而不是双精度数吗?或者有没有一种方法可以在不使用无痛脚本并使用具有指定精度和舍入模式的 java 的 BigDecimal 的情况下更改查询?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    它与 JavaScript 中的浮点数精度有关(类似于可以看到的 here 和解释 here)。

    这里有两种检查方法:

    A.如果你安装了 node.js,只需在提示符处输入node,然后输入所有 fieldA 值的总和:

     $ node
     108 - 36 - 7.2 + 14.85 + 36
     115.64999999999999            <--- this is the answer
    

    B.打开浏览器的开发者工具并选择控制台视图。然后输入与上面相同的总和:

     > 108-36-7.2+14.85+36
     < 115.64999999999999
    

    如您所见,这两个结果都与您在 ES 响应中看到的一致。

    避免这种情况的一种方法是将您的数字存储为普通整数(即 1485 而不是 14.85、3600 而不是 36 等)或 100 的 scaled_float with a scaling factor(或更大,取决于您需要的精度)

    【讨论】:

      猜你喜欢
      • 2019-10-15
      • 2020-11-20
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 2023-03-04
      • 2019-06-13
      相关资源
      最近更新 更多