# Type casting in Groovy reduce script of scripted metric aggregation

**URL:** <https://discuss.elastic.co/t/type-casting-in-groovy-reduce-script-of-scripted-metric-aggregation/32513>\
**Category:** Elasticsearch\
**Created:** [October 19, 2015, 5:38pm UTC](https://discuss.elastic.co/t/type-casting-in-groovy-reduce-script-of-scripted-metric-aggregation/32513 "2015-10-19T17:38:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![loren](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/loren/32/44942_2.png) [@loren](https://discuss.elastic.co/u/loren)\
**Post date:** [October 19, 2015, 5:38pm UTC](https://discuss.elastic.co/t/type-casting-in-groovy-reduce-script-of-scripted-metric-aggregation/32513/1 "2015-10-19T17:38:41Z")

</div>

I'm using the output of a scripted metric aggregation like the [one I describe here](https://discuss.elastic.co/t/how-would-you-query-elasticsearch-to-get-ratios/1222) as the payload for a Watcher condition. I'd expect the ratio of two numbers to also be a number, but it's coming back as a string unless I explicitly cast it as a float like this:

```auto
"reduce_script": "clicks = searches = 0; for (agg in _aggs) { clicks += agg.click ; searches += agg.search ;}; ctr_str = searches == 0 ? 0 : 100 * clicks / searches; return ctr_str.toFloat();"

```

or even

```auto
"reduce_script": "clicks = searches = 0; for (agg in _aggs) { clicks += agg.click ; searches += agg.search ;}; float ctr_str = searches == 0 ? 0 : 100 * clicks / searches; ctr_str;"

```

I'm not sure why I have to do this explicit casting though. Can anyone help this Groovy newbie out?

---

<div class="post-metadata">

**Author:** ![pickypg](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/pickypg/32/62409_2.png) [@pickypg](https://discuss.elastic.co/u/pickypg)\
**Post date:** [October 21, 2015, 5:52pm UTC](https://discuss.elastic.co/t/type-casting-in-groovy-reduce-script-of-scripted-metric-aggregation/32513/2 "2015-10-21T17:52:46Z")

</div>

The dynamic nature of things can often burn you as often as it can help you in Groovy, as it seems to be doing here. The core problem here is that Groovy does division with integers using `BigDecimal`, which ends up being a string when it's time to serialize it. You can prove this by using script fields to see what is happening (note: with `script.inline: on`):

```auto
PUT /test/type/1
{
  "field1" : 123,
  "field2" : 123
}

GET /test/_search
{
  "script_fields": {
    "FIELD": {
      "script": "(doc['field1'].value / doc['field2'].value).class"
    }
  }
}

```

This returns:

```auto
{
   "took": 64,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "test",
            "_type": "type",
            "_id": "1",
            "_score": 1,
            "fields": {
               "FIELD": [
                  "class java.math.BigDecimal"
               ]
            }
         }
      ]
   }
}

```

Your best bet is to cast the values to tip off Groovy what it needs to become before returning it. It's effectively what you're doing with toFloat();.

Another solution exists without casting, as you are using a constant of `100` in your calculation: change it to `100.0`, which will make it a `double` rather than an integer, and the result will automatically be a double as a result.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 11:43pm UTC](https://discuss.elastic.co/t/type-casting-in-groovy-reduce-script-of-scripted-metric-aggregation/32513/3 "2017-07-05T23:43:28Z")

</div>


