Distance feature

Distance feature query #

Recalls every document and scores each by its proximity to an origin — the closer, the higher:

score = boost × pivot / (pivot + distance(document, origin))

A document exactly at the origin scores boost; one pivot units away scores boost / 2. The decay is gradual — unlike a range filter, a document three pivots out still scores boost / 4, so nothing is excluded, only demoted. It answers “rank by recency or by distance” without a second index or a script.

POST /my-collection/_search
{
  "query": {
    "distance_feature": {
      "field": "production_date",
      "pivot": "7d",
      "origin": "now"
    }
  }
}

How it works #

The pivot’s unit decides what distance means for the query: a duration makes it a time difference (epoch millis, or raw nanos with a nanos pivot for date_nanos fields), a distance makes it metres (geo_point fields), and a plain number compares the field’s numeric values directly. Each document’s stored field value is read, its distance to the origin computed — absolute difference for numbers and dates, haversine for geo points — and run through the formula above; distance is floored at zero, so values on either side of the origin score identically.

origin resolves lazily: "now" pins at evaluation time (every segment of one request sees the same instant), an ISO-8601 date parses to epoch millis, a number passes through, and geo origins take the [lon, lat] array or the "lat,lon" string. Pivot durations accept ms, s, m, h, d, w and nanos/ns; distances accept km, m-less bare numbers (metres), mi, yd, ft, in, cm, mm and nmi. When a millis-scale pivot meets nanosecond-scale doc values (values ≥ 10^17), the values are divided down to millis so the two sides of the subtraction agree — the same normalization the date_nanos paths apply elsewhere.

The geo form, ranking every document by distance from one point:

POST /places/_search
{
  "query": {
    "distance_feature": {
      "field": "location",
      "pivot": "1000km",
      "origin": [116.4074, 39.9042]
    }
  }
}

Parameters for distance_feature #

  • field
    (Required, string) A numeric, date, date_nanos, or geo_point field.
  • origin
    (Required) The anchor: "now", an ISO-8601 date, an epoch number for numeric/date fields; [lon, lat] or "lat,lon" for geo fields.
  • pivot
    (Required) The distance at which the score halves: a duration ("1h", "7d", "100000000nanos"), a distance ("1km", "500m", "2mi"), or a plain number for numeric fields.
  • boost
    (Optional, float, default: 1.0).

Use cases #

  • Recency re-ranking. As a bool.should clause next to the text query, origin: "now" with pivot: "7d" adds up to one unit of score to fresh log lines and products — recent hits win ties without excluding old ones.
  • “Nearest first” without geo infrastructure. On a geo_point field, standalone distance_feature orders every place by distance from the shopper’s coordinates; pivot sets how quickly relevance falls off (within pivot, scores stay above half).
  • Freshness-ordered feeds. Standalone on a date field it is a pure recency sort whose scores are comparable across requests — handy for TTL dashboards and “last seen” views.
  • Nanos-precision timelines. date_nanos fields with a "100000000nanos" pivot (100 ms) resolve orderings that collapse at millisecond resolution.

Notes #

The query recalls every document that carries the field — each hit scores above zero, whether the value is stored as a number, an ISO date string, or any accepted geo form ([lon, lat] array or "lat,lon" string). Documents missing the field, or with values that do not parse for it, are simply not recalled. It pairs naturally as a bool.should clause (relevance re-ranking) or standalone as a recency/proximity ordering. Inside nested queries it is not supported yet (rejected with a named error).

  • hybrid — score_functions, the declarative alternative when the decay should combine with other scoring functions.
  • rescore — re-scoring the top window of an already-ranked result, the other place proximity boosts are applied.
  • geo_distance — the filter form: a hard radius that excludes, where distance_feature demotes.
  • sort — _geo_distance sorting when you need distance ordering without score decay.
Calendar October 7, 2026
Edit Edit this page