在特定时间内RANGE查询没有完全匹配

时间:2017-11-30 08:45:26

标签: elasticsearch range

问题

为什么Elasticsearch范围查询与时间不完全匹配" 2017-11-30T13:23:23.063657 + 11:00"?如果查询中存在错误或预期错误,请提示。

查询

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"
            }
        }
    }
}
'

预计只有一个匹配的数据如下。

{
  "_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
    ]
  }
}

结果

然而,它匹配了更接近时间的多个记录。

"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"
  }
}
...

1 个答案:

答案 0 :(得分:1)

Elasticsearch使用Joda-Time来解析日期。而你的问题是Joda-Time只将日期/时间值存储到毫秒。

来自docs

  

库内部使用毫秒瞬间,它是相同的   到JDK和类似于其他常见的时间表示。这个   使互操作性变得简单,Joda-Time带有开箱即用的功能   JDK互操作性。

这意味着在解析日期时不会考虑秒的最后3位数。

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

都解释为:
2017-11-30T13:23:23.063+11:00

所有这些值的相应纪元时间为1512008603063

您也可以通过向查询中添加explain来查看此内容:

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

这基本上就是所有这些文件都与您的查询相符的原因。