Elasticsearch analytics percent Elasticsearch analytics percent elasticsearch elasticsearch

Elasticsearch analytics percent


With ES 1.7.3, there is no way to compute data based on the results of two different aggregations, this is something that can be done in ES 2.0 with pipeline aggregations, though.

However, what you're asking is not too complicated to do on the client-side with 1.7.3. If you use the query below, you'll get all you need to get the figures you expect:

POST components/_search{   "size": 0,   "aggs": {      "total_duration": {         "sum": {            "field": "duration"         }      },      "components": {         "terms": {            "field": "component"         },         "aggs": {            "duration_sum": {               "sum": {                  "field": "duration"               }            }         }      }   }}

The results would look like this:

{   "took": 1,   "timed_out": false,   "_shards": {      "total": 5,      "successful": 5,      "failed": 0   },   "hits": {      "total": 4,      "max_score": 0,      "hits": []   },   "aggregations": {      "total_duration": {         "value": 44      },      "components": {         "doc_count_error_upper_bound": 0,         "sum_other_doc_count": 0,         "buckets": [            {               "key": "a",               "doc_count": 2,               "duration_sum": {                  "value": 15               }            },            {               "key": "b",               "doc_count": 1,               "duration_sum": {                  "value": 27               }            },            {               "key": "c",               "doc_count": 1,               "duration_sum": {                  "value": 2               }            }         ]      }   }}

Now all you need to do would be the following. I'm using JavaScript, but you can do it in any other language that can read JSON.

var response = ...the JSON response above...var total_duration = response.aggregations.total_duration.value;var total_docs = response.hits.total;response.aggregations.components.buckets.forEach(function(comp_stats) {    // total duration for the component    var total_duration_comp = comp_stats.duration_sum.value;    // percentage duration of the component    var perc_duration_comp = total_duration_comp / total_duration * 100;    // percentage documents for the component    var perc_doc_comp = comp_stats.doc_count / total_docs * 100;});


In ElasticSearch[2.x], You can use the bucket script aggregation, which is perfectly meet your needs!

eg:

{    "bucket_script": {        "buckets_path": {            "my_var1": "the_sum",             "my_var2": "the_value_count"        },        "script": "my_var1 / my_var2"    }}

detail:

POST /sales/_search{    "size": 0,    "aggs" : {        "sales_per_month" : {            "date_histogram" : {                "field" : "date",                "interval" : "month"            },            "aggs": {                "total_sales": {                    "sum": {                        "field": "price"                    }                },                "t-shirts": {                  "filter": {                    "term": {                      "type": "t-shirt"                    }                  },                  "aggs": {                    "sales": {                      "sum": {                        "field": "price"                      }                    }                  }                },                "t-shirt-percentage": {                    "bucket_script": {                        "buckets_path": {                          "tShirtSales": "t-shirts>sales",                          "totalSales": "total_sales"                        },                        "script": "params.tShirtSales / params.totalSales * 100"                    }                }            }        }    }}