elasticsearchelasticsearch-dslelasticsearch-queryrange-query

How to query if a time is between two field values


How do I search for documents that are between a start and end time? For example, I want to query the following document using a time only like "18:33" or "21:32". "18:33" would return the following document and "21:32" wouldn't. I don't care about the date part nor the secs.

{
  "my start time field": "2020-01-23T18:32:21.768Z",
  "my end time field": "2020-01-23T20:32:21.768Z"
}

I've reviewed: Using the range query with date fields. but I'm not sure how to only look at times. Also, I want to see if a time is between two fields, not if a field is between two times.


Essentially, the Elasticsearch equivalent of BETWEEN for SQL Server. Like this answer except I don't want to use the current time but a variable.

DECLARE @blah datetime2 = GETDATE()

SELECT  *
FROM Table1 T
WHERE CAST(@blah AS TIME) 
      BETWEEN cast(T.StartDate as TIME) AND cast(T.EndDate as TIME)

Solution

  • As per the suggestion from the OP and the link he provided which adheres to the laws of stackoverflow I'm providing the second solution in here:

    Solution 2: Insert separate fields for hour minute as hh:mm

    Note the format used which says hour_minute. You can find the list of formats available under the aforementioned link.

    Basically you re-ingest the documents with a separate field that would have hour and minute values and execute range queries to get what you want.

    Mapping:

    PUT my_time_index
    {
      "mappings": {
        "properties": {
          "start_time":{
            "type": "date",
            "format": "hour_minute"
          },
          "end_time":{
            "type": "date",
            "format": "hour_minute"
          }
        }
      }
    }
    

    Sample Document:

    POST my_time_index/_doc/1
    {
      "start_time": "18:32",
      "end_time": "20:32"
    }
    

    Query Request:

    POST my_time_index/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "range": {
                "start_time": {
                  "gte": "18:00"
                }
              }
            },
            {
              "range": {
                "end_time": {
                  "lte": "21:00"
                }
              }
            }
          ]
        }
      }
    }
    

    Let me know if this helps!