﻿---
title: Range field types
description: 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...
url: https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/range
products:
  - Elasticsearch
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available
---

# Range field types
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 [histogram](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-bucket-histogram-aggregation), [cardinality](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-cardinality-aggregation).
The following range types are supported:
<definitions>
  <definition term="integer_range">
    A range of signed 32-bit integers with a minimum value of `-2^31` and maximum of `2^31 - 1`.
  </definition>
  <definition term="float_range">
    A range of single-precision 32-bit IEEE 754 floating point values.
  </definition>
  <definition term="long_range">
    A range of signed 64-bit integers with a minimum value of `-2^63` and maximum of `2^63 - 1`.
  </definition>
  <definition term="double_range">
    A range of double-precision 64-bit IEEE 754 floating point values.
  </definition>
  <definition term="date_range">
    A range of [`date`](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/date) values. Date ranges support various date formats through the [`format`](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/mapping-date-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](/elastic/docs-builder/docs/3016/reference/elasticsearch/rest-apis/common-options#date-math) expression are not supported.
  </definition>
  <definition term="ip_range">
    A range of ip values supporting either [IPv4](https://en.wikipedia.org/wiki/IPv4) or [IPv6](https://en.wikipedia.org/wiki/IPv6) (or mixed) addresses.
  </definition>
</definitions>

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

{
  "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"
      }
    }
  }
}


{
  "expected_attendees" : { <2>
    "gte" : 10,
    "lt" : 20
  },
  "time_frame" : {
    "gte" : "2015-10-31 12:00:00", <3>
    "lte" : "2015-11-01"
  }
}
```

The following is an example of a [term query](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/query-languages/query-dsl/query-dsl-term-query) on the `integer_range` field named "expected_attendees". 12 is a value inside the range, so it will match.
```json

{
  "query" : {
    "term" : {
      "expected_attendees" : {
        "value": 12
      }
    }
  }
}
```

The result produced by the above query.
```json
{
  "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",
        "_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"
          }
        }
      }
    ]
  }
}
```

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

{
  "query" : {
    "range" : {
      "time_frame" : { <1>
        "gte" : "2015-10-31",
        "lte" : "2015-11-01",
        "relation" : "within" <2>
      }
    }
  }
}
```

This query produces a similar result:
```json
{
  "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",
        "_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"
          }
        }
      }
    ]
  }
}
```


## IP Range

In addition to the range format above, IP ranges can be provided in [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) notation:
```json

{
  "properties": {
    "ip_allowlist": {
      "type": "ip_range"
    }
  }
}


{
  "ip_allowlist" : "192.168.0.0/16"
}
```


## Parameters for range fields

The following parameters are accepted by range types:
<definitions>
  <definition term="coerce">
    Try to convert strings to numbers and truncate fractions for integers. Accepts `true` (default) and `false`.
  </definition>
  <definition term="doc_values">
    Should the field be stored on disk in a column-stride fashion, so that it can later be used for sorting, aggregations, or scripting? Accepts `true` (default) or `false`.
  </definition>
  <definition term="index">
    Should the field be searchable? Accepts `true` (default) and `false`.
  </definition>
  <definition term="store">
    Whether the field value should be stored and retrievable separately from the [`_source`](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/mapping-source-field) field. Accepts `true` or `false` (default).
  </definition>
</definitions>


## Sorting

Sorting is not supported for any of the `range` field types. Attempting to sort by a field of type range_field will result in a `400 Bad Request` response.
For example, executing a sort query on a field of type `integer_range`,
```json

{
  "mappings": {
    "properties": {
      "my_range": {
        "type": "integer_range"
      }
    }
  }
}


{
  "sort": [
    {
      "my_range": {
        "order": "asc"
      }
    }
  ]
}
```

results in the following response:
```json
{
    "error": {
        "root_cause": [
            {
                "type": "illegal_argument_exception",
                "reason": "Sorting by range field [my_range] is not supported"
            }
        ],
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "phase": "query",
        "grouped": true,
        "failed_shards": [
            {
                "shard": 0,
                "index": "idx",
                "node": "7pzVSCf5TuSNZYj-N7u3tw",
                "reason": {
                    "type": "illegal_argument_exception",
                    "reason": "Sorting by range field [my_range] is not supported"
                }
            }
        ],
        "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "Sorting by range field [my_range] is not supported",
            "caused_by": {
                "type": "illegal_argument_exception",
                "reason": "Sorting by range field [my_range] is not supported"
            }
        }
    },
    "status": 400
}
```


## Synthetic `_source`

`range` fields support [synthetic `_source`](/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/mapping-source-field#synthetic-source) in their default configuration.
Synthetic source may sort `range` field values and remove duplicates for all `range` fields except `ip_range`. Ranges are sorted by their lower bound and then by upper bound. For example:

```json

{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_range": { "type": "long_range" }
    }
  }
}


{
  "my_range": [
    {
        "gte": 200,
        "lte": 300
    },
    {
        "gte": 1,
        "lte": 100
    },
    {
        "gte": 200,
        "lte": 300
    },
    {
        "gte": 200,
        "lte": 500
    }
  ]
}
```

Will become:
```json
{
  "my_range": [
    {
        "gte": 1,
        "lte": 100
    },
    {
        "gte": 200,
        "lte": 300
    },
    {
        "gte": 200,
        "lte": 500
    }
  ]
}
```

Values of `ip_range` fields are not sorted but original order is not preserved. Duplicate ranges are removed. If `ip_range` field value is provided as a CIDR, it will be represented as a range of IP addresses in synthetic source.
For example:

```json

{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_range": { "type": "ip_range" }
    }
  }
}


{
  "my_range": [
    "10.0.0.0/24",
    {
      "gte": "10.0.0.0",
      "lte": "10.0.0.255"
    }
  ]
}
```

Will become:
```json
{
  "my_range": {
      "gte": "10.0.0.0",
      "lte": "10.0.0.255"
    }

}
```


Range field values are always represented as inclusive on both sides with bounds adjusted accordingly. Default values for range bounds are represented as `null`. This is true even if range bound was explicitly provided. For example:

```json

{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_range": { "type": "long_range" }
    }
  }
}


{
  "my_range": {
    "gt": 200,
    "lt": 300
  }
}
```

Will become:
```json
{
  "my_range": {
    "gte": 201,
    "lte": 299
  }
}
```


Default values for range bounds are represented as `null` in synthetic source. This is true even if range bound was explicitly provided with default value. For example:

```json

{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_range": { "type": "integer_range" }
    }
  }
}


{
  "my_range": {
    "lte": 2147483647
  }
}
```

Will become:
```json
{
  "my_range": {
    "gte": null,
    "lte": null
  }
}
```

`date` ranges are formatted using provided `format` or by default using `yyyy-MM-dd'T'HH:mm:ss.SSSZ` format. For example:

```json

{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_range": { "type": "date_range" }
    }
  }
}


{
  "my_range": [
    {
      "gte": 1504224000000,
      "lte": 1504569600000
    },
    {
      "gte": "2017-09-01",
      "lte": "2017-09-10"
    }
  ]
}
```

Will become:
```json
{
  "my_range": [
    {
      "gte": "2017-09-01T00:00:00.000Z",
      "lte": "2017-09-05T00:00:00.000Z"
    },
    {
      "gte": "2017-09-01T00:00:00.000Z",
      "lte": "2017-09-10T23:59:59.999Z"
    }
  ]
}
```