elasticsearch nested aggregate based on attribute and get custom value based on a formula in every bucket -
i have dataset of event actions:
{"person" : "person1", "event" : "e1", "action" : "like"} {"person" : "person2", "event" : "e1", "action" : "dislike"} {"person" : "person1", "event" : "e1", "action" : "share"} {"person" : "person1", "event" : "e1", "action" : "rating"} {"person" : "person1", "event" : "e2", "action" : "rating"}
can aggregate based on event , on bucket, based on weighted metrics on actions single custom value bucket?
i have done nested aggregation:
{ "size": 0, "aggs": { "all_events": { "terms": { "field": "event.keyword" }, "aggs": { "overall_ratings": { "terms": { "field": "action.keyword" } } } } }
}
so result:
- e1 -> - 10, dislike: 4, share: 8
- e2 -> - 30, dislike: 0, share: 2
but want apply formula get
- e1 -> (like*5) + (dislike* -3) + (share*2) = (10*5)+(4*-3)+(8*2) = 50-12+16= 54
i want:
- e1 -> 54
- e2 -> 154
yes, possible, can build quite complicated formulas aggregations. use scripted metric aggregations.
in example - data provied - result should be:
e1 -> (1*5) + (1*-3) + (1*2) = 5 - 3 + 2 = 4 e2 -> 0
the aggregating query have be:
{ "size": 0, "aggs": { "all_events": { "terms": { "field": "event.keyword" }, "aggs": { "overall_ratings": { "scripted_metric": { "init_script": "params._agg.transactions = [];", "map_script": "if (doc.action.value == 'like') params._agg.transactions.add(5); if (doc.action.value == 'dislike') params._agg.transactions.add(-3); if (doc.action.value == 'share') params._agg.transactions.add(2);", "combine_script" : "int total = 0; (t in params._agg.transactions) { total += t; } return total;", "reduce_script" : "int total = 0; (a in params._aggs) { total += a; } return total;" } } } } } }
and query gave me following result:
{ "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 5, "max_score": 0, "hits": [] }, "aggregations": { "all_events": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "e1", "doc_count": 4, "overall_ratings": { "value": 4 } }, { "key": "e2", "doc_count": 1, "overall_ratings": { "value": 0 } } ] } } }
one importanat thing - may necessary have action
field set in mapping "fielddata": true
:
"action": { "type": "text", ..., "fielddata": true }
otherwise you'll exception "fielddata disabled on text fields default...."
Comments
Post a Comment