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.

Each range then places the document: from is inclusive, to is exclusive, both in metres. Ranges are checked independently, so overlapping ranges double-count a document, and every declared range produces exactly one bucket — in declaration order, empty ones included. A bucket without an explicit key is named "{from}-{to}" with * for the unbounded side (*-500000, 500000-*). Nested sub-aggregations run per ring over that ring’s documents.

Examples #

Ring the Beijing area origin at 500 km:

Two places fall inside 500 km, thirteen beyond — matching the geo_distance query answer:

{
  ...
  "aggregations": {
    "by_distance": {
      "buckets": [
        { "key": "*-500000", "doc_count": 2 },
        { "key": "500000-*", "doc_count": 13 }
      ]
    }
  }
}

Use cases #

  • Radius reporting. “Stores within 50 km / 50–200 km / beyond” as one request — the classic store-locator bands.
  • Delivery-zone coverage. Ring a warehouse origin and nest a sum per ring to weigh each zone’s demand, not just count it.
  • Local-vs-remote splits. Any near/far comparison around a fixed point: users near an event, sensors near a fault line.
  • Query faceting. Combine with a geo_bounding_box query so the rings summarize only the mapped viewport.

Parameters for geo_distance #

  • field
    (Required, string) geo_point field you wish to aggregate.
  • origin
    (Required, object) { "lat": …, "lon": … } center point (a "lat,lon" string is also accepted).
  • ranges
    (Required, object array) Buckets with optional from / to in metres (from inclusive, to exclusive); key names a bucket.
  • aggs
    (Optional, object) Nested sub-aggregations, computed per ring.

Distances are always computed and reported in metres; the unit and distance_type parameters are not accepted.

Calendar October 6, 2026
Edit Edit this page