BigDecimal Result in scripted_metric aggregation is returned as string

Hi,

When result of scripted_metric aggregation is instance of BigDecimal, the returned value from the aggregation is stringified Number. Whereas if the result of scripted_metric is Integer/Double , the returned value is Number.

Case 1:

Elasticsearch Query

{
    "size": 0,
    "aggs": {
        "metric": {
            "scripted_metric": {
                "map_script": "",
                "reduce_script": "34.23"
            }
        }
    }
}

Elasticsearch Result

{
   "took": 11,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 19496,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "metric": {
         "value": 34.23
      }
   }
}

Case 2:

Elasticsearch Query

{
    "size": 0,
    "aggs": {
        "metric": {
            "scripted_metric": {
                "map_script": "",
                "reduce_script": "34/23"
            }
        }
    }
}

Elasticsearch Result

{
   "took": 16,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 19496,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "metric": {
         "value": "1.4782608696"
      }
   }
}

In case1, metric.value is 34.23 which is a number and in case2, metric.value is "1.4782608696".

Can someone explain why this happens ?

It's because Groovy defaults to using BigDecimal for all math operations involving floating points. And to prevent loss of precision, it encodes the BigDecimal as a string (since, theoretically, it could have much more precision than a double).

That said... don't use BigDecimal if you can help it. They are slow, and have plenty of their own edgecases. It's pretty silly that Groovy chose to make them default...

If you force the value to be a Double you should be better off:

{
    "size": 0,
    "aggs": {
        "metric": {
            "scripted_metric": {
                "map_script": "",
                "reduce_script": "34/23D"
            }
        }
    }
}