[[java-aggs-metrics-scripted-metric]] ==== Scripted Metric Aggregation Here is how you can use {ref}/search-aggregations-metrics-scripted-metric-aggregation.html[Scripted Metric Aggregation] with Java API. ===== Prepare aggregation request Here is an example on how to create the aggregation request: [source,java] -------------------------------------------------- MetricsAggregationBuilder aggregation = AggregationBuilders .scriptedMetric("agg") .initScript("_agg['heights'] = []") .mapScript(new Script("if (doc['gender'].value == \"male\") " + "{ _agg.heights.add(doc['height'].value) } " + "else " + "{ _agg.heights.add(-1 * doc['height'].value) }")); -------------------------------------------------- You can also specify a `combine` script which will be executed on each shard: [source,java] -------------------------------------------------- MetricsAggregationBuilder aggregation = AggregationBuilders .scriptedMetric("agg") .initScript(new Script("_agg['heights'] = []")) .mapScript(new Script("if (doc['gender'].value == \"male\") " + "{ _agg.heights.add(doc['height'].value) } " + "else " + "{ _agg.heights.add(-1 * doc['height'].value) }")) .combineScript(new Script("heights_sum = 0; for (t in _agg.heights) { heights_sum += t }; return heights_sum")); -------------------------------------------------- You can also specify a `reduce` script which will be executed on the node which gets the request: [source,java] -------------------------------------------------- MetricsAggregationBuilder aggregation = AggregationBuilders .scriptedMetric("agg") .initScript(new Script("_agg['heights'] = []")) .mapScript(new Script("if (doc['gender'].value == \"male\") " + "{ _agg.heights.add(doc['height'].value) } " + "else " + "{ _agg.heights.add(-1 * doc['height'].value) }")) .combineScript(new Script("heights_sum = 0; for (t in _agg.heights) { heights_sum += t }; return heights_sum")) .reduceScript(new Script("heights_sum = 0; for (a in _aggs) { heights_sum += a }; return heights_sum")); -------------------------------------------------- ===== Use aggregation response Import Aggregation definition classes: [source,java] -------------------------------------------------- import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.metrics.tophits.TopHits; -------------------------------------------------- [source,java] -------------------------------------------------- // sr is here your SearchResponse object ScriptedMetric agg = sr.getAggregations().get("agg"); Object scriptedResult = agg.aggregation(); logger.info("scriptedResult [{}]", scriptedResult); -------------------------------------------------- Note that the result depends on the script you built. For the first example, this will basically produce: [source,text] -------------------------------------------------- scriptedResult object [ArrayList] scriptedResult [ { "heights" : [ 1.122218480146643, -1.8148918111233887, -1.7626731575142909, ... ] }, { "heights" : [ -0.8046067304119863, -2.0785486707864553, -1.9183567430207953, ... ] }, { "heights" : [ 2.092635728868694, 1.5697545960886536, 1.8826954461968808, ... ] }, { "heights" : [ -2.1863201099468403, 1.6328549117346856, -1.7078288405893842, ... ] }, { "heights" : [ 1.6043904836424177, -2.0736538674414025, 0.9898266674373053, ... ] } ] -------------------------------------------------- The second example will produce: [source,text] -------------------------------------------------- scriptedResult object [ArrayList] scriptedResult [-41.279615707402876, -60.88007362339038, 38.823270659734256, 14.840192739445632, 11.300902755741326] -------------------------------------------------- The last example will produce: [source,text] -------------------------------------------------- scriptedResult object [Double] scriptedResult [2.171917696507009] --------------------------------------------------