Elasticsearch - Bucket_script和buckets_paths返回“找不到聚合器类型”

时间:2016-11-04 10:55:00

标签: elasticsearch buckets

我正在尝试用Elasticsearch计算一些百分比,但我有一个(小)问题。我希望ES计算以下内容:“(wins / Total)* 100”。

所以我补充道:

"bucket_script": {
      "buckets_paths": {
        "total": "TotalStatus",
        "wins": "TotalWins"
      },
      "script": " (total/ wins) * 100"
}

我的ES请求,如下所示:

{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "*",
            "analyze_wildcard": true
          }
        }
      ],
      "must_not": []
    }
  },
  "aggs": {
   "status": {
      "terms": {
        "field": "status.raw"
      }
    },
    "wins": {
      "terms": {
        "field": "status.raw",
        "include": {
          "pattern": "Accepted|Released|Closed"
        }
      }
    },
    "losses": {
      "terms": {
        "field": "status.raw",
        "include": {
          "pattern": "Rejected"
        }
      }
    },
     "TotalStatus": {
      "sum_bucket": {
        "buckets_path": "status._count"
      }
    },
   "TotalWins": {
      "sum_bucket": {
        "buckets_path": "wins._count"
      }
    },
   "TotalLosses": {
      "sum_bucket": {
        "buckets_path": "losses._count"
      }
    }
  }
}

然而,这会返回以下错误:

{
  "error": {
    "root_cause": [
      {
        "type": "parsing_exception",
        "reason": "Could not find aggregator type [buckets_paths] in [bucket_script]",
        "line": 54,
        "col": 28
      }
    ],
    "type": "parsing_exception",
    "reason": "Could not find aggregator type [buckets_paths] in [bucket_script]",
    "line": 54,
    "col": 28
  },
  "status": 400
}

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我用bucket_script玩过很多次但是我想它可能不可能,因为它不能是顶级聚合,而且你需要来自同一父聚合的total_wins和total_status都有一个数值而我认为这可能是不可能的。

但可以通过scripted metric aggregation

解决
{
  "size": 0,
  "aggs": {
    "win_loss_ratio": {
      "scripted_metric": {
        "init_script": "_agg['win_count'] = 0; _agg['total_count'] = 0; _agg['win_status']=['Accepted','Released','Closed'];",
        "map_script": "if (doc['status.raw'].value in _agg['win_status']) { _agg['win_count']+=1};if (doc['status.raw'].value) { _agg['total_count']+=1}",
        "combine_script": "return [_agg['win_count'],_agg['total_count']];",
        "reduce_script": "total_win = 0; total_status_count=0; for (a in _aggs) { total_win += a[0]; total_status_count += a[1] }; if(total_win == 0) {return 0} else {return (total_status_count/total_win) * 100}"
      }
    }
  }
}
  • init_script 初始化三个变量。 win_status 数组包含与win status对应的所有值。
  • map_script 遍历每个文档,如果 status.raw 值在 win_status 中,则 win_count 会增加如果它有任何值 total_count 会增加(如果您还想包含空值,则可以删除此条件)
  • combine_script 获取每个分片的所有值
  • reduce_script 对所有值求和,然后对其进行除法。还有一个检查,以便我们不要除以零或脚本将抛出异常。