mon
mon

Reputation: 22244

No exact match for RANGE query for a specific time

Question

Why does the Elasticsearch Range query not exact match with the time "2017-11-30T13:23:23.063657+11:00"? Kindly suggest if there is a mistake in the query or it is expected.

Query

curl -XGET 'https://hostname/_search?pretty' -H 'Content-Type: application/json' -d'
{
    "query": {
        "range" : {
            "time" : {
                "gte": "2017-11-30T13:23:23.063657+11:00",
                "lte": "2017-11-30T13:23:23.063657+11:00"
            }
        }
    }
}
'

The expected only one data to match is below.

{
  "_index": "***",
  "_source": {
    "time": "2017-11-30T13:23:23.063657+11:00",
    "log_level": "INFO",
    "log_time": "2017-11-30 13:23:23,042"
  },
  "fields": {
    "time": [
      1512008603063
    ]
  }
}

Result

However, it matched multiple records which is closer to the time.

"hits" : {
"total" : 11,
"max_score" : 1.0,
"hits" : [ {
  "_index" : "***",
  "_score" : 1.0,
  "_source" : {
    "time" : "2017-11-30T13:23:23.063612+11:00",
    "log_level" : "INFO",
    "log_time" : "2017-11-30 13:23:23,016"
  }
}, {
  "_index" : "core-apis-non-prod.97d5f1ee-a570-11e6-b038-02dc30517283.2017.11.30",
  "_score" : 1.0,
  "_source" : {
    "time" : "2017-11-30T13:23:23.063722+11:00",  
    "log_level" : "INFO",
    "log_time" : "2017-11-30 13:23:23,046"
  }
}
...

Upvotes: 2

Views: 60

Answers (1)

Diyarbakir
Diyarbakir

Reputation: 2099

Elasticsearch uses Joda-Time for parsing dates. And your problem is that Joda-Time only stores date/time values down to the millisecond.

From the docs:

The library internally uses a millisecond instant which is identical to the JDK and similar to other common time representations. This makes interoperability easy, and Joda-Time comes with out-of-the-box JDK interoperability.

This means that the last 3 digits of the seconds are not taken into account when parsing the date.

2017-11-30T13:23:23.063612+11:00
2017-11-30T13:23:23.063657+11:00
2017-11-30T13:23:23.063722+11:00

Are all interpreted as:
2017-11-30T13:23:23.063+11:00

And the corresponding epoch time is 1512008603063 for all these values.

You can see this too by adding explain to the query like this:

{
    "query": {
        "range" : {
            "time" : {
                "gte": "2017-11-30T13:23:23.063657+11:00",
                "lte": "2017-11-30T13:23:23.063657+11:00"
            }
        }
    }, 
    "explain": true
}

That is basically the reason all those documents match your query.

Upvotes: 1

Related Questions