How To Use the Range API in Elasticsearch Queries 257

Have a Database Problem? Speak with an Expert for Free
Get Started >>

Introduction

When you’re querying your Elasticsearch data, there are times when you’ll have a certain range in mind. You may want to return documents that fall within a certain data range, or you might want to find all the students within a certain age range. Regardless of your particular criteria, the Range API makes it easy to specify various ranges in your queries. In this step-by-step tutorial, we’ll explain how to create range queries in Elasticsearch.

Prerequisites

Before we attempt to use the Range API in Elasticsearch, it’s important to ensure that certain prerequisites are in place. For this task, the system requirements are minimal: An Elasticsearch cluster needs to be running, and you need to have at least one index with a mapping schema that includes numerical data, such as integers or dates, so that you can use it to test some range queries.

Range datatypes allowed

Elasticsearch allows users to pass Java 32- and 64-bit primitive datatypes in queries. This means that any 32-bit integer, 64-bit long-integer or float (which includes the double-type double-precision floating point) is allowed to be passed as a parameter in a range query.

Different parameters for the Range API

Elasticsearch is built on Lucene and thus uses Lucene query syntax. The Lucene range query has a few different parameters that you can pass into the "range" field to narrow down your search query:

Use the following operators to query for any document with a numeric field whose value is: gte — greater than, or equal to a number gt — greater than a given number lte — less than, or equal to a number lt — less than a given number

Range Queries in Elasticsearch

Greater Than and Less Than Queries:

Combining the greater than (gt) and less than (lt) range parameters is an effective way to search for documents that contain a certain field value within a range where you know the upper and lower bounds.

In this example, we can find all cars that were made in 2016, 2017, and 2018:

1
2
3
4
5
6
7
8
9
10
11
12
curl -X GET "localhost:9200/cars/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"year" : {
"gte" : 2016,
"lte" : 2018
}
}
}
}
'

Here’s the same query executed in Kibana:

1
2
3
4
5
6
7
8
9
10
11
GET /cars/_search
{
"query": {
"range" : {
"year" : {
"gte" : 2016,
"lte" : 2018
}
}
}
}

If you’d like to find just the car models from 2017, simply leave off the e from the operators, and use "gt" and "lt" instead.

A Kibana request looking for all of the 'cars' documents with a model year greater than or equal to 2016, and less than or equal to 2018

Date Range Queries

Many common queries involve date ranges as a parameter. You can query any "date" mapping field type within specific date ranges. You’re able to specify the "format" of the date, and you can pass the parameters 'contains", "intersects", and "relation" into the query as well.

Here’s an example of a range query to get documents within a date range:

1
2
3
4
5
6
7
8
9
10
11
12
13
curl -X GET "localhost:9200/cars/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query" : {
"range" : {
"added_to_lot" : {
"gte" : "2017-03-01",
"lte" : "2018-02-28",
"relation" : "within"
}
}
}
}
'

The range query in Kibana returned a total of 116 "hits" in an Elasticsearch index containing over 500 documents:

Screenshot of a request in Kibana to make a range query of a date field for an Elasticsearch index using the "relation" option

Date range format combinations:

If you’re querying a date range between two specific times, you can also “mix and match” two different date formats for the range. The following example will return all cars added to the lot on any day in 2017 as well as any day in 2018 that was on or before June 12th:

1
2
3
4
"added_to_lot" : {
"gte": "2017",
"lte": "06/12/2018"
}

Parse date field exception:

When you query an index using a range query that contains a date field, it’s important to adhere to the date format specified in that index’s mapping. The example we just looked at actually returns a "parse date field exception, because the "added_to_lot" field for the index was mapped with an explicit format:

1
2
3
4
"added_to_lot": {
"type": "date",
"format": "yyyy-MM-dd"
},

You can see that the mapping for added_to_lot specifies a "yyyy-MM-dd" format, but our query used a "MM/dd/yyyy" format. Make sure to refer to the index’s mapping before making range query requests:

1
GET cars/_mapping

Using the boost option in range queries

The boost field is another option that allows you to make individual fields have more influence on a document’s relevance score. The value of boost acts as a multiplier– adding a boost of 2 will give matches for part of the query twice the weight.

For example, if you’d like a certain range query for the car models that are newer than 2017 to have a boost in relevancy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Kibana --> GET /cars/_search

curl -X GET "localhost:9200/cars/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"year" : {
"gte": "2017",
"boost": 3.0
}
}
}
}
'

All of the "hits" returned from this query will have a "max_score", or relevance score, of 3.0.

When this parameter is omitted, the boost setting defaults to 1.0.

Conclusion

When you make queries to Elasticsearch, sometimes you have a range in mind for your search criteria. Fortunately, the Range API makes it quick and simple to create range queries for Elasticsearch. In our examples, we queried for documents with a certain date range and for cars made in specific years. Armed with the instructions provided in this article, it will be easy to use the Range API for all of your own search needs.

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.