脚本化聚合计算,结果出乎意料

时间:2020-03-14 22:07:04

标签: elasticsearch searchkick

首先,我对ES / SK还是陌生的,而对于农业来说更是如此。

这是我的aggs结构:

  aggs: {
    all_budgets: {
      sum: {
        field: :amount
      }
    },
    all_forecasts: {
      sum: {
        field: :forecast_total
      }
    },
    all_variance: {
      sum: {
        script: "doc['forecast_total'].value - doc['amount'].value"
      }
    },
    all_variance_p: {
      sum: {
        script: "(doc['forecast_total'].value - doc['amount'].value) / doc['amount'].value"
      }
    }

  }

我基本上是在尝试获取所有预算的总和,总支出,然后是预算的超出/低于预算以及相应的百分比。这是我的输出:

{
  "all_forecasts": {
    "doc_count": 2,
    "value": 173604.0
  },
  "all_budgets": {
    "doc_count": 2,
    "value": 185437.0
  },
  "all_variance_p": {
    "doc_count": 2,
    "value": "0.33694326595832774"
  },
  "all_variance": {
    "doc_count": 2,
    "value": -11833.0
  }
}

“ 0.33694326595832774”值错误-应该为“ -0.06408106257”(即-11833.0 / 185437.0)。前两个脚本有效,我怀疑我不了解这些脚本的工作原理。

2 个答案:

答案 0 :(得分:0)

在除法之前,请尝试将数字强制转换为相同的datatype。例如((float)(doc['forecast_total'].value) - (float)(doc['amount'].value)) / (float)(doc['amount'].value))

答案 1 :(得分:0)

为响应您对访问all_budgets和all_forecasts的最终值进行进一步计算的评论,可以使用bucket script aggregation,它可以使用存储桶路径访问父聚合。由于需要使用存储分区,因此您需要添加父汇总ex date_histogram,该父汇总可以按给定的时间间隔(年,月或日等)拆分文档

{
  "size": 0,
  "aggs": {
    "year_interval": {
      "date_histogram": {
        "field": "timestamp",
        "interval": "year"
      },
      "aggs": {
        "all_budgets": {
          "sum": {
            "field": "amount"
          }
        },
        "all_forecasts": {
          "sum": {
            "field": "forecast"
          }
        },
        "all_variance": {
          "bucket_script": {
            "buckets_path": {
              "total_forecast":"all_forecasts",
              "total_budget":"all_budgets"
            },
            "script": "params.total_forecast-params.total_budget"
          }
        },
        "all_variance_p": {
          "bucket_script": {
            "buckets_path": {
              "variance":"all_variance",
              "budget":"all_budgets"
            },
            "script": "params.variance/params.budget"
          }
        }
      }
    }
  }
}