xtingray
xtingray

Reputation: 503

ElasticSearch: How to query a date field using an hours-range filter

Currently, I already know how to filter a days range from a (timestamp) date field. That's an easy one:

"range": {
    "date": {
        "gte": "2015-11-01",
        "lte": "2015-11-30"
    }
}

But how to filter dates when you are interested in ranges based on hours like gte:"8:00:00" and lte:"10:00:00"? Is this possible?

My requirement in other words: How to get all the events happening this month (15-11-01/15-11-30) but only between 8:00:00 am and 10:00:00?

Upvotes: 21

Views: 45839

Answers (3)

ChintanShah25
ChintanShah25

Reputation: 12672

If I understood your question correctly then I think you have to add new field which indexes only time like

PUT your_index
{
  "mappings": {
    "your_type": {
      "properties": {
        "time": {
          "type":   "date",
          "format": "HH:mm:ss"
        }
      }
    }
  }
}

Then you can query like this

{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "date": {
              "gte": "2015-11-01",
              "lte": "2015-11-30"
            }
          }
        },
        {
          "range": {
            "time": {
              "gte": "08:00:00",
              "lte": "10:00:00"
            }
          }
        }
      ]
    }
  }
}

Does this help?

Upvotes: 6

icyerasor
icyerasor

Reputation: 5242

Here's what I once used to only get results from start of current day to 6pm:

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "(log_message:\"My Search String\")"
          }
        },
        {
          "range": {
            "@timestamp": {
              "time_zone": "CET",
              "gt": "now-24h/d",
              "lte": "now-24h/d+18h"
            }
          }
        }
      ]
    }
  }
}

the important part is "now-24h/d" which will round to midnight / begin of current day, although it is a bit tricky as it depends on whether you use gt/lt(e), see reference doc for details.

Upvotes: 4

Val
Val

Reputation: 217504

You can do it with your range filter to filter the correct days and then with a script filter to filter the desired hours, like this:

{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "range": {
                "date": {
                  "gte": "2015-11-01",
                  "lte": "2015-11-30"
                }
              }
            },
            {
              "script": {
                "script": {
                  "source": "doc.date.date.getHourOfDay() >= params.min && doc.date.date.getHourOfDay() <= params.max",
                  "params": {
                    "min": 8,
                    "max": 10
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

Note that you need to make sure to enable dynamic scripting in order for this query to work.

Upvotes: 22

Related Questions