2016-11-04 259 views
0

我試圖用Elasticsearch來計算一些百分比,但我有一個(小)問題。我希望ES計算以下內容:「(勝/總數)* 100」。Elasticsearch - Bucket_script和buckets_paths返回「無法找到聚合器類型」

於是我說:

"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 
} 

任何想法的?

+0

您正在運行哪個版本的ES? – Val

+0

最新最棒的:5.0.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數組具有與贏狀態相對應的所有值。
  • map_script遍歷每個文檔,如果status.raw值是win_status然後win_count遞增,如果它在所有TOTAL_COUNT遞增的任何值(你可以,如果條件刪除此如果你還希望包括空值)
  • combine_script得到每碎片的所有值
  • reduce_script總和所有的值,然後迪提供它。還有一個檢查,以便我們不用零除或腳本會拋出異常。
+0

返回:http://pastebin.com/bk3n5r4a:/ –

+0

我已經提交了一個[類似的bug](https://github.com/elastic/elasticsearch/pull/19863 )並且我的PR尚未合併,但是您可以通過在'script_metric'聚合中定義''params':{「_agg」:{}}來超前。 – Val

+0

我剛試過這個,不幸的是它也不起作用。這是圖像:http://imgur.com/a/8Brqx –