Range queries

Oftentimes, we need a set of data that falls within a range: flights that were delayed between certain dates, profit sales on a particular day, pupils with average height in a class, and so on. Elasticsearch provides a range query for these types of inquiries.

The range query returns the documents for a range in a field. The query accepts lower and upper bounds on the field. If we need to fetch all the movies for a rating between 9.0 and 9.5, for example, we can execute the range query in the following listing:

GET movies/_search
{
"query": {
"range": {
"rating": {
"gte": 9.0,
"lte": 9.5
}
}
}
}

In the listing, the range query fetches the movies that fall within the specified rating brackets. The rating field is an object that accepts bounds, which are defined as operators. The following table shows the operators that we can use to specify the range.

Operators in a range query

We use range queries for searching across a range of dates or numbers. If you want to fetch all the movies after 1970, for example, you simply stitch the query as the next listing shows.

GET movies/_search
{
"query": {
"range": {
"release_date": {
"gte": "01-01-1970"
}
}
},
"sort": [{
"release_date": {
"order": "asc"
}
}]
}

The release_date declares a gte operator with the search requirement; in this case, the year 1970. Notice that we also sort the movies in ascending order on the release date using the sort attribute in the query. The results of the movies returned are therefore oldest to newest.

Because we are discussing range queries, let’s use this opportunity to go over date math in a range query. We discuss this in the following section.

Range queries with data math

Elasticsearch supports sophisticated data math in queries. For example, we can ask the engine questions like:

  • Fetch the book sales a couple of days back (current day minus two days).
  • Find the access denied errors in the last 10 minutes (current hour minus 10 minutes).
  • Get the tweets for a particular search criteria from last year.

Elasticsearch expects a specific date expression that deals with data math:

an anchor date followed by || is the first part of the expression, appended with the time we want to add or subtract from the anchor date: anchor date plus or minus a set number of hours, days, or years.

For example, to fetch movies two days after a specific day (say, 1st of January 2022), we form the expression as 01-01-2022||+2d

The first part of the expression (01–01–2022) is called an anchor date, whereas the || indicates that the anchor date is being manipulated either by adding or by subtracting a certain number of time units (minutes, seconds, years, days, etc.).

For example, we want to fetch the movies released a couple of days back, so we set the anchor date as today (as of writing, today’s date is 20–10–2022) and subtract two days as this listing shows:

GET movies/_search
{
"query": {
"range": {
"release_date": {
"lte": "20-10-2022||-2d"
}
}
}
}

As you can see in the listing, the range query’s lte operator takes a date value expressed as date math. In this case, 20–10-2022 is the anchor date, and we subtract two days from it.

Instead of mentioning the current date specifically, Elasticsearch lets us use a specific keyword: now.

For example, using now-1y sets the date to one year back as the next listing shows.

GET movies/_search
{
"query": {
"range": {
"release_date": {
"lte": "now-1y"
}
}
}
}

We looked at range queries in this section – the type of queries which helps fetch a set of documents given a range parameters. If you find these articles helpful, follow me (and give me a clap :)). Stay tuned for more!

These short articles are condensed excerpts taken from my book Elasticsearch in Action, Second Edition. The code is available in my GitHub repository.

Elasticsearch in Action