Aggregation

Bucket selector aggregation

/ Bucket_selector, / Aggregation

Bucket selector aggregation #

A parent pipeline aggregation filtering the bucket list itself: a script predicate per bucket — buckets whose script evaluates false are dropped from the response. It is the HAVING clause of the aggregation world: the predicate sees computed metrics, not documents.

"big_days": {
  "bucket_selector": {
    "buckets_path": { "r": "revenue" },
    "script": "params.r > 150"
  }
}

How it works #

bucket_selector is declared inside the multi-bucket aggregation it decorates, next to the metrics it consumes. After the buckets are built, the engine resolves each named path against every bucket, evaluates the script once as a boolean, and removes the buckets that fail from the owning aggregation’s response. The selector itself never appears in the output — it is a filter, not a metric.

...

Diversified sampler aggregation

/ Diversified_sampler, / Aggregation

Diversified sampler aggregation #

Like sampler, but the sample is diversified by a field — up to one (or few) documents per value — so rare categories survive the sampling. A plain sampler can be flooded by the most common value (every sampled type being t-shirt); the diversified variant guarantees representation for every distinct value first.

How it works #

The sampler walks the matching documents in two passes. First it caps each distinct value of the diversify field at max_docs_per_value (default 1) — extra documents with an already-full value are dropped. Documents missing the diversify field share one common group. The survivors are then sorted and truncated to the overall shard_size (default 100).

...

Geo bounds aggregation

/ Geo_bounds, / Aggregation

Geo bounds aggregation #

A metrics aggregation computing the bounding box (top-left / bottom-right corners) of all geo_point values — the rectangle that just contains every point in the bucket.

How it works #

The engine scans the bucket’s geo_point column, tracks the minimum and maximum latitude and longitude, and emits:

{
  "bounds": {
    "top_left":     { "lat": <max lat>, "lon": <min lon> },
    "bottom_right": { "lat": <min lat>, "lon": <max lon> }
  }
}

null when the bucket holds no parseable point. The column-store fast path and the executor path run the same min/max scan.

...

Bucket sort aggregation

/ Bucket_sort, / Aggregation

Bucket sort aggregation #

A parent pipeline aggregation sorting (and paginating) the bucket list by any of the bucket’s metrics — the pipeline counterpart of the request-level sort.

"by_revenue": {
  "bucket_sort": { "sort": [ { "revenue": { "order": "asc" } } ] }
}

How it works #

Status, verified against the engine: bucket_sort is accepted but not yet active. The request parses — sort, from and size are accepted — but no reordering or truncation is applied: the parent aggregation’s buckets come back in the parent’s own order. A declared bucket_sort evaluates to a null metric, and nested declarations currently leave a "by_revenue": { "value": null } placeholder in each bucket (unlike bucket_selector, it does not clean up after itself).

...

Geo centroid aggregation

/ Geo_centroid, / Aggregation

Geo centroid aggregation #

A metrics aggregation computing the centroid (mean latitude and longitude) of all geo_point values.

How it works #

The engine sums latitudes and longitudes across the bucket’s geo_point values and divides by the count:

{
  "location": { "lat": .., "lon": .. },
  "count": 15
}
  • The mean is arithmetic per axis (a planar average, not spherical) — exact enough at city or country scale, drifting only for extents that cross the 180th meridian or span hemispheres.
  • Every parseable point counts once; there is no weight field. The result is null when the bucket holds no points.
  • Under distributed fan-out the coordinator keeps its own shard’s value (geo metrics have no mergeable intermediate), so single-node results are the exact ones.
  • Like every geo_point consumer, the aggregation sees points normalized at ingestion: {"lat": .., "lon": ..}, [lon, lat] (longitude first) or a "lat,lon" string, all stored as two-dimensional BKD points.

Examples #

Returns the count of points and their centroid — the natural center point for map placement. Over the 15 places: count: 15, location about {lat 31.7484, lon 111.2181}.

...

Geo distance aggregation

/ Geo_distance, / Aggregation

Geo distance aggregation #

A multi-bucket aggregation like range, but buckets are distance rings around a geo_point origin. It answers “how many things are near me?” — counts per radius band in a single request, no matter how many rings you declare.

How it works #

Every document’s point is measured against the origin with the haversine formula on a spherical Earth (mean radius 6,371,008.8 m — within ~0.5 % of the WGS-84 ellipsoid). The origin accepts either a "lat,lon" string or a { "lat": …, "lon": … } object; an origin that parses to nothing yields zero buckets.

...

Geohash grid aggregation

/ Geohash_grid, / Aggregation

Geohash grid aggregation #

A multi-bucket aggregation that groups geo_point values into geohash cells — the building block of map clustering. It answers “where are my documents concentrated?” in one request, handing the map a count per cell instead of thousands of individual markers.

How it works #

Each document’s point is encoded as a geohash string: base-32 characters produced by interleaving longitude and latitude bits over successively halved intervals. precision is the number of characters kept — 1–12, clamped, default 5 (cells of roughly 4.9 km × 4.9 km). The classic Amsterdam coordinate 52.374081, 4.912350 at precision 3 lands in cell u17.

...

Normalize aggregation

/ Normalize, / Aggregation

Normalize aggregation #

A parent pipeline aggregation rescaling a bucket metric into a share or rank — e.g. each bucket’s revenue as a percent of the total (percent_of_sum), a 0..1 position (rescale_0_1), or standard deviations from the mean (z-score).

"share": {
  "normalize": { "buckets_path": "per_type>revenue", "method": "percent_of_sum" }
}

How it works #

In this engine normalize is evaluated in the sibling placement: declare it next to the bucket aggregation and point buckets_path at the series with the full parent>metric form. The engine collects one value per bucket, applies the chosen method across the whole series, and emits a standalone buckets array (keys 0..n−1) with one value per consumed bucket.

...

Top hits aggregation

/ Top_hits, / Aggregation

Top hits aggregation #

Keeps track of the most relevant documents being aggregated — useful inside a bucket aggregation (e.g. terms) to return the best-matching documents per bucket. Where most metric aggs reduce a bucket to one number, top_hits keeps the documents themselves.

How it works #

top_hits runs over a bucket’s document set and returns up to size documents in a hits envelope: hits.total — a plain count of the bucket’s documents — and hits.hits[], each entry carrying _id (the engine’s internal numeric document id) and _source.

...

Geotile grid aggregation

/ Geotile_grid, / Aggregation

Geotile grid aggregation #

A multi-bucket aggregation grouping geo_point values into zoom/x/y map tiles — the native grid of web maps. Where geohash_grid speaks in geohash strings, this one emits exactly the tile addresses a Leaflet/MapLibre layer already understands, so clustering needs no coordinate translation.

How it works #

Each point is mapped to its Web-Mercator tile: x and y are computed from longitude/latitude scaled by 2^zoom, latitude clamped to the projection’s ±85.0511° limit. precision is the zoom level — 0–29, default 7 (a tile spans ~300 km at the equator; each zoom step halves it). The bucket key is the z/x/y string, e.g. Amsterdam at zoom 8 → 8/131/84.

...