弹性搜索日期范围查询

时间:2020-02-17 11:31:10

标签: elasticsearch kibana elasticsearch-mapping

我是弹性搜索的新手,并且正在为日期范围查询而苦苦挣扎。我必须查询介于某些特定日期之间的记录。推送到弹性搜索数据库中的JSON记录如下:

                "messageid": "Some message id",
                "subject": "subject",
                "emaildate": "2020-01-01 21:09:24",
                "starttime": "2020-01-02 12:30:00",
                "endtime": "2020-01-02 13:00:00",
                "meetinglocation": "some location",
                "duration": "00:30:00",
                "employeename": "Name",
                "emailid": "abc@xyz.com",
                "employeecode": "141479",
                "username": "username",
                "organizer": "Some name",
                "organizer_email": "cde@xyz.com",

我必须查询开始时间在“ 2020-01-02 12:30:00”到“ 2020-01-10 12:30:00”之间的记录。我写了这样的查询:

{
   "query":
      {
        "bool":
           {

              "filter": [
                {
                    "range" : {
                        "starttime": { 
                             "gte": "2020-01-02 12:30:00", 
                             "lte": "2020-01-10 12:30:00" 
                         }
                    }
                }
              ]            
           } 
      }
}

此查询未提供预期的结果。我假设将数据推送到我办公室的弹性搜索数据库中的人员尚未设置映射,并且弹性搜索正在动态地将“开始时间”的数据类型确定为“文本”。因此,我得到的结果不一致。 我可以这样设置映射:

PUT /meetings
{
  "mappings": {
    "dynamic": false,
    "properties": {
        .
        .
        .
        .
      "starttime": {
        "type": "date",
        "format":"yyyy-MM-dd HH:mm:ss"
      }
        .
        .
        .
    }
  }
}

该查询将起作用,但不允许这样做(办公政策)。我有什么其他选择可以完成任务。

更新:

我假设数据类型为“文本”,但是默认情况下,弹性搜索同时应用“文本”和“关键字”,因此我们可以实现基于全文和关键字的搜索。如果还设置为“关键字”。无论如何,这对我有好处吗?我无法在办公室中访问很多东西,这就是为什么我无法调试查询。我只有要为其构建查询的搜索API。

获取/会议/ _mapping输出:

  '
  '
  '
 "starttime" : {
        "type" : "text",
        "fields" : {
          "keyword" : {
            "type" : "keyword",
            "ignore_above" : 256
          }
        }
  }

    '
    '
    ' 

3 个答案:

答案 0 :(得分:1)

日期范围查询不适用于文本字段,为此,您必须使用日期字段

由于您正在处理日期字段,因此最佳实践是使用日期字段。

我建议您将索引重新索引为另一个索引,以便可以将文本字段的类型更改为日期字段

第1步:使用index1映射创建index2,并确保将日期字段的类型(即文本更改为日期类型)

第2步:运行elasticsearch重新索引并将所有数据从index1重新索引到index2。由于您已将字段类型更改为日期字段类型。 Elasticsearch现在将把该字段识别为日期

<mat-checkbox>

现在您可以在index2上运行普通日期查询

答案 1 :(得分:0)

有几种方法可以在搜索时将文本字段解析为日期,但是开销并不现实...但是,您可以将starttime保留为默认文本,但是将其设置为multi-field并进行查询例如,使用starttime.as_date

答案 2 :(得分:0)

正如@jzzfs所建议的,想法是在date字段中添加一个starttime子字段。您首先需要像这样修改映射:

PUT meetings/_mapping
{
  "properties": {
     "starttime" : {
        "type" : "text",
        "fields" : {
          "keyword" : {
            "type" : "keyword",
            "ignore_above" : 256
          },
          "date": {
            "type" : "date",
            "format" : "yyyy-MM-dd HH:mm:ss",
          }
        }
     }
  }
}

完成后,您需要使用update by query API重新索引数据,以便填充starttime.date字段并建立索引:

POST meetings/_update_by_query

更新完成后,您将可以利用查询中的starttime.date子字段:

{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "starttime.date": {
              "gte": "2020-01-02 12:30:00",
              "lte": "2020-01-10 12:30:00"
            }
          }
        }
      ]
    }
  }
}