Elasticsearch查询日期范围不起作用

时间:2018-08-09 11:31:04

标签: python elasticsearch

我正在尝试查询ElasticSearch以获取两个时间戳之间的结果。 典型的记录如下

{
   "_index": "cost-2018.08.09",
   "_type": "log",
   "_id": "asdasdasxsa-sdsds",
   "_score": 4.281278,
   "_source": {
      "index": "cost-2018.08.09",
      "app_group": "shop",
      "timestamp": "2018-08-09T00:00:04.349692"
   }
}

我用来从两个时间戳之间的shop中检索每个app_group的查询:

GET /cost-2018.08.09/_search?q=app_group:shop 
{
  "query": {
    "range": {
      "timestamp": {
        "gte": "2018-08-09 04:00:04",
        "lt": "2018-08-09 04:30:06"
      }
    }
  }

仅返回每个shop,但不检查任何timestamp。奇怪的是,即使我故意在查询中包含错误:

GET /cost-2018.08.09/_search?q=app_group:shop
{
  "query": {
    "range": {
      "timestamp": {
        "gte": "2018-08-asdadsx09 04:00:04",
        "lt": "2018-08-09asdasd 04:30:06"
      }
    }
 }

我得到了完全相同的答案。就像它没有考虑query

一些注意事项: 在Python中,我的代码如下:

result = es_client.search(index='cost-2018.07.26', q='app_group:shop', filter_path=['hits.hits._source'], body={
        "query": {
            "range": {
              "timestamp": {
                 "gte": "2018-08-09 04:00:04",
                 "lt": "2018-08-09 04:30:06"
              }
           }
         }
    })

记录的timestamp字段确实被解释为date而不是String

我想念什么?

1 个答案:

答案 0 :(得分:1)

(请注意,此答案是对于Elasticsearch 6.3

对我有用的是adding a mapping when creating the index.

在映射中,您指定字段将保存的数据类型,并指定日期为you can also set a format的情况。

{
    "mappings":{
        "_doc":{
            "timestamp": {
                "format": "yyyy-MM-dd'T'HH:mm:ss'Z'",
                "type": "date"
            },
        }
    }
}

在此示例中,格式适用于我所使用的特定用例but you can set it up however you need

这应允许您进行日期范围查询,如以下示例所示:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "app_group": "shop"
          }
        }
      ],
      "filter": [
        {
          "range" : {
            "timestamp" : {
                "gte": "2018-08-15T00:00:00Z", 
                "lte": "2018-08-15T23:00:00Z"
                }
            }
        }
      ]
    }
  }
}

请注意,我使用的格式与您使用的格式略有不同。

更多详细信息:

在我的特定情况下,我对结果有疑问,因为我需要与搜索词完全匹配,以避免产生相关但不相关的结果。

在您的情况下,由于您正在搜索特定的“ app_group”,因此似乎也可能会遇到此问题。

要启用确切的搜索,可以使用以下映射:

{
  "settings":{
    "index":{
      "analysis":{
        "analyzer":{
          "analyzer_case_insensitive":{
            "tokenizer":"keyword",
            "filter":"lowercase"
          }
        }
      }
    }
  },
  "mappings":{
    "_doc":{
      "properties":{
        "app_group":{
          "type":"string",
          "analyzer":"analyzer_case_insensitive"
        }
      }
    }
  }
}

(在这个very useful blog post中,我在StackOverflow和其他地方遇到了几种过时的方法后发现了这一点)

基本上,所提供的设置是在让索引器执行use the keyword tokenizer并应用the lowercase filter,以便您的搜索不区分大小写(即首先将所有内容都转换为小写,因此您可以搜索“ app_group = shop”或“ app_group = Shop”等。

最终的映射应类似于此(除了您自己的日期格式):

{
  "settings":{
    "index":{
      "analysis":{
        "analyzer":{
          "analyzer_case_insensitive":{
            "tokenizer":"keyword",
            "filter":"lowercase"
          }
        }
      }
    }
  },

  "mappings": {
    "_doc": {
      "properties": {
        "timestamp": {
          "type":   "date",
          "format": "yyyy-MM-dd'T'HH:mm:ss'Z'"
        },
        "app_group": {
          "type":"text",
          "analyzer":"analyzer_case_insensitive"
        }
      }
    }
  }
}