Metrics aggregations

Min Aggregation

Here is how you can use Min Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .min("agg")
                .field("height");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.min.Min;
// sr is here your SearchResponse object
Min agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Max Aggregation

Here is how you can use Max Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .max("agg")
                .field("height");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.max.Max;
// sr is here your SearchResponse object
Max agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Sum Aggregation

Here is how you can use Sum Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .sum("agg")
                .field("height");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.sum.Sum;
// sr is here your SearchResponse object
Sum agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Avg Aggregation

Here is how you can use Avg Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .avg("agg")
                .field("height");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.avg.Avg;
// sr is here your SearchResponse object
Avg agg = sr.getAggregations().get("agg");
double value = agg.getValue();

Stats Aggregation

Here is how you can use Stats Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .stats("agg")
                .field("height");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.stats.Stats;
// sr is here your SearchResponse object
Stats agg = sr.getAggregations().get("agg");
double min = agg.getMin();
double max = agg.getMax();
double avg = agg.getAvg();
double sum = agg.getSum();
long count = agg.getCount();

Extended Stats Aggregation

Here is how you can use Extended Stats Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .extendedStats("agg")
                .field("height");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStats;
// sr is here your SearchResponse object
ExtendedStats agg = sr.getAggregations().get("agg");
double min = agg.getMin();
double max = agg.getMax();
double avg = agg.getAvg();
double sum = agg.getSum();
long count = agg.getCount();
double stdDeviation = agg.getStdDeviation();
double sumOfSquares = agg.getSumOfSquares();
double variance = agg.getVariance();

Value Count Aggregation

Here is how you can use Value Count Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .count("agg")
                .field("height");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
// sr is here your SearchResponse object
ValueCount agg = sr.getAggregations().get("agg");
long value = agg.getValue();

Percentile Aggregation

Here is how you can use Percentile Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .percentiles("agg")
                .field("height");

You can provide your own percentiles instead of using defaults:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .percentiles("agg")
                .field("height")
                .percentiles(1.0, 5.0, 10.0, 20.0, 30.0, 75.0, 95.0, 99.0);

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentiles;
// sr is here your SearchResponse object
Percentiles agg = sr.getAggregations().get("agg");
// For each entry
for (Percentile entry : agg) {
    double percent = entry.getPercent();    // Percent
    double value = entry.getValue();        // Value

    logger.info("percent [{}], value [{}]", percent, value);
}

This will basically produce for the first example:

percent [1.0], value [0.814338896154595]
percent [5.0], value [0.8761912455821302]
percent [25.0], value [1.173346540141847]
percent [50.0], value [1.5432023318692198]
percent [75.0], value [1.923915462033674]
percent [95.0], value [2.2273644908535335]
percent [99.0], value [2.284989339108279]

Percentile Ranks Aggregation

Here is how you can use Percentile Ranks Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .percentileRanks("agg")
                .field("height")
                .percentiles(1.24, 1.91, 2.22);

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
import org.elasticsearch.search.aggregations.metrics.percentiles.PercentileRanks;
// sr is here your SearchResponse object
PercentileRanks agg = sr.getAggregations().get("agg");
// For each entry
for (Percentile entry : agg) {
    double percent = entry.getPercent();    // Percent
    double value = entry.getValue();        // Value

    logger.info("percent [{}], value [{}]", percent, value);
}

This will basically produce:

percent [29.664353095090945], value [1.24]
percent [73.9335313461868], value [1.91]
percent [94.40095147327283], value [2.22]

Cardinality Aggregation

Here is how you can use Cardinality Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .cardinality("agg")
                .field("tags");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
// sr is here your SearchResponse object
Cardinality agg = sr.getAggregations().get("agg");
long value = agg.getValue();

Cardinality Aggregation

Here is how you can use Geo Bounds Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

GeoBoundsBuilder aggregation =
        AggregationBuilders
                .geoBounds("agg")
                .field("address.location")
                .wrapLongitude(true);

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.metrics.geobounds.GeoBounds;
// sr is here your SearchResponse object
GeoBounds agg = sr.getAggregations().get("agg");
GeoPoint bottomRight = agg.bottomRight();
GeoPoint topLeft = agg.topLeft();
logger.info("bottomRight {}, topLeft {}", bottomRight, topLeft);

This will basically produce:

bottomRight [40.70500764381921, 13.952946866893775], topLeft [53.49603022435221, -4.190029308156676]

Top Hits Aggregation

Here is how you can use Top Hits Aggregation with Java API.

Prepare aggregation request

Here is an example on how to create the aggregation request:

AggregationBuilder aggregation =
    AggregationBuilders
        .terms("agg").field("gender")
        .subAggregation(
            AggregationBuilders.topHits("top")
        );

You can use most of the options available for standard search such as from, size, sort, highlight, explain…​

AggregationBuilder aggregation =
    AggregationBuilders
        .terms("agg").field("gender")
        .subAggregation(
            AggregationBuilders.topHits("top")
                .setExplain(true)
                .setSize(1)
                .setFrom(10)
        );

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
// sr is here your SearchResponse object
Terms agg = sr.getAggregations().get("agg");

// For each entry
for (Terms.Bucket entry : agg.getBuckets()) {
    String key = entry.getKey();                    // bucket key
    long docCount = entry.getDocCount();            // Doc count
    logger.info("key [{}], doc_count [{}]", key, docCount);

    // We ask for top_hits for each bucket
    TopHits topHits = entry.getAggregations().get("top");
    for (SearchHit hit : topHits.getHits().getHits()) {
        logger.info(" -> id [{}], _source [{}]", hit.getId(), hit.getSourceAsString());
    }
}

This will basically produce for the first example:

key [male], doc_count [5107]
 -> id [AUnzSZze9k7PKXtq04x2], _source [{"gender":"male",...}]
 -> id [AUnzSZzj9k7PKXtq04x4], _source [{"gender":"male",...}]
 -> id [AUnzSZzl9k7PKXtq04x5], _source [{"gender":"male",...}]
key [female], doc_count [4893]
 -> id [AUnzSZzM9k7PKXtq04xy], _source [{"gender":"female",...}]
 -> id [AUnzSZzp9k7PKXtq04x8], _source [{"gender":"female",...}]
 -> id [AUnzSZ0W9k7PKXtq04yS], _source [{"gender":"female",...}]

Scripted Metric Aggregation

Here is how you can use Scripted Metric Aggregation with Java API.

Don’t forget to add Groovy in your classpath if you want to run Groovy scripts in an embedded data node (for unit tests for example). For example, with Maven, add this dependency to your pom.xml file:

<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <version>2.3.2</version>
    <classifier>indy</classifier>
</dependency>

Prepare aggregation request

Here is an example on how to create the aggregation request:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .scriptedMetric("agg")
                .initScript("_agg['heights'] = []")
                .mapScript("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:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .scriptedMetric("agg")
                .initScript("_agg['heights'] = []")
                .mapScript("if (doc['gender'].value == \"male\") " +
                        "{ _agg.heights.add(doc['height'].value) } " +
                        "else " +
                        "{ _agg.heights.add(-1 * doc['height'].value) }")
                .combineScript("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:

MetricsAggregationBuilder aggregation =
        AggregationBuilders
                .scriptedMetric("agg")
                .initScript("_agg['heights'] = []")
                .mapScript("if (doc['gender'].value == \"male\") " +
                        "{ _agg.heights.add(doc['height'].value) } " +
                        "else " +
                        "{ _agg.heights.add(-1 * doc['height'].value) }")
                .combineScript("heights_sum = 0; for (t in _agg.heights) { heights_sum += t }; return heights_sum")
                .reduceScript("heights_sum = 0; for (a in _aggs) { heights_sum += a }; return heights_sum");

Use aggregation response

Import Aggregation definition classes:

import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
// 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:

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:

scriptedResult object [ArrayList]
scriptedResult [-41.279615707402876,
                -60.88007362339038,
                38.823270659734256,
                14.840192739445632,
                11.300902755741326]

The last example will produce:

scriptedResult object [Double]
scriptedResult [2.171917696507009]