[[range]]
=== Range field types
++++
<titleabbrev>Range</titleabbrev>
++++

Range field types represent a continuous range of values between an upper and lower
bound. For example, a range can represent _any date in October_ or _any
integer from 0 to 9_. They are defined using the operators
`gt` or `gte` for the lower bound, and `lt` or `lte` for the upper bound.
They can be used for querying, and have
limited support for aggregations. The only supported aggregations are
{ref}/search-aggregations-bucket-histogram-aggregation.html[histogram],
{ref}/search-aggregations-metrics-cardinality-aggregation.html[cardinality].

The following range types are supported:

[horizontal]
`integer_range`::   A range of signed 32-bit integers with a minimum value of +-2^31^+ and maximum of +2^31^-1+.
`float_range`::     A range of single-precision 32-bit IEEE 754 floating point values.
`long_range`::      A range of signed 64-bit integers with a minimum value of +-2^63^+ and maximum of +2^63^-1+.
`double_range`::    A range of double-precision 64-bit IEEE 754 floating point values.
`date_range`::      A range of <<date,`date`>> values. Date ranges support various date formats
                    through the <<mapping-date-format,`format`>> mapping parameter. Regardless of
                    the format used, date values are parsed into an unsigned 64-bit integer
                    representing milliseconds since the Unix epoch in UTC. Values containing the
                    `now` <<date-math,date math>> expression are not supported.
`ip_range` ::       A range of ip values supporting either {wikipedia}/IPv4[IPv4] or
                    {wikipedia}/IPv6[IPv6] (or mixed) addresses.

Below is an example of configuring a mapping with various range fields followed by an example that indexes several range types.

[source,console]
--------------------------------------------------
PUT range_index
{
  "settings": {
    "number_of_shards": 2
  },
  "mappings": {
    "properties": {
      "expected_attendees": {
        "type": "integer_range"
      },
      "time_frame": {
        "type": "date_range", <1>
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}

PUT range_index/_doc/1?refresh
{
  "expected_attendees" : { <2>
    "gte" : 10,
    "lt" : 20
  },
  "time_frame" : {
    "gte" : "2015-10-31 12:00:00", <3>
    "lte" : "2015-11-01"
  }
}
--------------------------------------------------
// TESTSETUP

<1> `date_range` types accept the same field parameters defined by the <<date, `date`>> type.
<2> Example indexing a meeting with 10 to 20 attendees, not including 20.
<3> Example date range using date time stamp.

The following is an example of a <<query-dsl-term-query, term query>> on the `integer_range` field named "expected_attendees".
12 is a value inside the range, so it will match.

[source,console]
--------------------------------------------------
GET range_index/_search
{
  "query" : {
    "term" : {
      "expected_attendees" : {
        "value": 12
      }
    }
  }
}
--------------------------------------------------

The result produced by the above query.

[source,console-result]
--------------------------------------------------
{
  "took": 13,
  "timed_out": false,
  "_shards" : {
    "total": 2,
    "successful": 2,
    "skipped" : 0,
    "failed": 0
  },
  "hits" : {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "range_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "expected_attendees" : {
            "gte" : 10, "lt" : 20
          },
          "time_frame" : {
            "gte" : "2015-10-31 12:00:00", "lte" : "2015-11-01"
          }
        }
      }
    ]
  }
}
--------------------------------------------------
// TESTRESPONSE[s/"took": 13/"took" : $body.took/]

The following is an example of a `date_range` query over the `date_range` field named "time_frame".

[source,console]
--------------------------------------------------
GET range_index/_search
{
  "query" : {
    "range" : {
      "time_frame" : { <1>
        "gte" : "2015-10-31",
        "lte" : "2015-11-01",
        "relation" : "within" <2>
      }
    }
  }
}
--------------------------------------------------

<1> Range queries work the same as described in <<query-dsl-range-query, range query>>.
<2> Range queries over range <<mapping-types, fields>> support a `relation` parameter which can be one of `WITHIN`, `CONTAINS`,
    `INTERSECTS` (default).

This query produces a similar result:

[source,console-result]
--------------------------------------------------
{
  "took": 13,
  "timed_out": false,
  "_shards" : {
    "total": 2,
    "successful": 2,
    "skipped" : 0,
    "failed": 0
  },
  "hits" : {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "range_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "expected_attendees" : {
            "gte" : 10, "lt" : 20
          },
          "time_frame" : {
            "gte" : "2015-10-31 12:00:00", "lte" : "2015-11-01"
          }
        }
      }
    ]
  }
}
--------------------------------------------------
// TESTRESPONSE[s/"took": 13/"took" : $body.took/]

[[ip-range]]
==== IP Range

In addition to the range format above, IP ranges can be provided in
{wikipedia}/Classless_Inter-Domain_Routing#CIDR_notation[CIDR] notation:

[source,console]
--------------------------------------------------
PUT range_index/_mapping
{
  "properties": {
    "ip_allowlist": {
      "type": "ip_range"
    }
  }
}

PUT range_index/_doc/2
{
  "ip_allowlist" : "192.168.0.0/16"
}
--------------------------------------------------

[[range-params]]
==== Parameters for range fields

The following parameters are accepted by range types:

[horizontal]

<<coerce,`coerce`>>::

    Try to convert strings to numbers and truncate fractions for integers.
    Accepts `true` (default) and `false`.

<<mapping-boost,`boost`>>::

    Mapping field-level query time boosting. Accepts a floating point number, defaults
    to `1.0`.

<<mapping-index,`index`>>::

    Should the field be searchable? Accepts `true` (default) and `false`.

<<mapping-store,`store`>>::

    Whether the field value should be stored and retrievable separately from
    the <<mapping-source-field,`_source`>> field. Accepts `true` or `false`
    (default).
