弹性搜索日期范围查询

Elastic Search Date Range Query

我是弹性搜索的新手,我正在为日期范围查询而苦苦挣扎。我必须查询落入弹性搜索数据库的某些特定 dates.The 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" 
                         }
                    }
                }
              ]            
           } 
      }
}

此查询未提供预期的结果。我假设将数据推送到我办公室的 Elastic Search 数据库的人没有设置映射,Elastic Search 正在动态决定 "starttime" 的数据类型为 "text"。因此我得到不一致的结果。 我可以这样设置映射:

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

而且查询会起作用,但不允许我这样做(办公室政策)。我有什么选择可以完成我的任务。

更新:

我假定数据类型为 "Text",但默认情况下 Elastic Search 同时应用 "Text" 和 "Keyword",因此我们可以实现基于全文和关键字的搜索。如果也设置为 "Keyword" 。无论如何,这对我有好处吗?我无法访问办公室中的很多东西,这就是为什么我无法调试 query.I 只有搜索 API 我必须为其构建查询的原因。

GET /meetings/_mapping 输出:

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

    '
    '
    ' 

有一些方法可以在搜索时将文本字段解析为日期,但开销不切实际...但是,您可以将 starttime 默认保留为文本,但将其设为 multi-field并使用 starttime.as_date 查询它,例如。

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

由于您正在处理日期字段,最佳做法是使用日期字段。

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

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

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

POST _reindex
 { 
"source":{ "index": "index1" },
 "dest": { "index": "index2" }
 }

现在您可以运行 索引 2 上的正常日期查询

正如@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"
            }
          }
        }
      ]
    }
  }
}