简体   繁体   English

Elasticsearch 如何在日期时间字段中按时间搜索

[英]Elasticsearch how to search by time in datetime field

I have a imaginary index test with below mapping我有一个带有以下映射的虚构索引test

PUT test
{"mappings" : {
      "properties" : {
        "endTs" : {
          "type" : "date",
          "format": "yyyy-MM-dd HH:mm:ss",
          "index": true
        },
        "startTs" : {
          "type" : "date",
          "format": "yyyy-MM-dd HH:mm:ss",
          "index": true
        }
      }
    }
}

And add some value like below并添加一些值,如下所示

POST _bulk
{ "index" : { "_index" : "test"} }
{ "startTs": "2020-01-01 00:00:00", "endTs": "2020-01-01 00:15:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:15:00", "endTs" : "2020-01-01 00:30:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:30:00", "endTs" : "2020-01-01 00:45:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:45:00", "endTs" : "2020-01-01 01:00:00" }
{ "index" : { "_index" : "test"} }
{ "startTs": "2020-01-01 01:00:00", "endTs": "2020-01-01 01:15:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:15:00", "endTs" : "2020-01-01 01:30:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:30:00", "endTs" : "2020-01-01 01:45:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:45:00", "endTs" : "2020-01-01 02:00:00" }

My goal is to run some range query within this startTs and endTs field.我的目标是在这个startTsendTs字段中运行一些范围查询。 like startTs: 2020-01-01 00:00:00' and endTs: 2020-01-01 00:45:00' .比如startTs: 2020-01-01 00:00:00'endTs: 2020-01-01 00:45:00' I need to fo filter only with time not full datetime format.我只需要使用time而不是完整的datetime时间格式进行过滤。 So I tried below filter所以我尝试了下面的过滤器

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "startTs": {
              "gte": "00:00:00",
              "format": "HH:mm:ss"
            }
          }
        },
        {
          "range": {
            "endTs": {
              "lte": "00:45:00",
              "format": "HH:mm:ss"
            }
          }
        }
      ]
    }
  }
}

I expected it will return all the record value less then equal to 2020-01-01 00:45:00我预计它将返回小于等于2020-01-01 00:45:00的所有记录值

{ "startTs": "2020-01-01 00:00:00", "endTs": "2020-01-01 00:15:00" }
{ "startTs" : "2020-01-01 00:15:00", "endTs" : "2020-01-01 00:30:00" }
{ "startTs" : "2020-01-01 00:30:00", "endTs" : "2020-01-01 00:45:00" }

But It didn't return anything at all.但它根本没有返回任何东西。

"hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }

Then I tried然后我尝试了

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "script": {
            "script": {
              "source": "doc['startTs'].value.minute >= 0"
            }
          }
        },
        {
          "script": {
            "script": {
              "source": "doc['endTs'].value.minute <= 45"
            }
          }
        }
      ]
    }
  }
}

It return all the value that hase minute less than equal 45 and that is also not expected.它返回所有分钟小于等于 45 的值,这也是不期望的。

How to run the query for the given index with time range?如何对具有时间范围的给定索引运行查询? any help is highly appreciated.非常感谢任何帮助。

I am using elasticsearch 7.6我正在使用elasticsearch 7.6

Instead of indexing a date type I suggest that you index an integer with the number of minutes or seconds (depends on the resolution you need) since the beginning of the day.我建议您不要索引date类型,而是使用自一天开始以来的分钟数或秒数(取决于您需要的分辨率)索引integer Then run a range query against this field.然后对该字段运行范围查询。

The date type doesn't support the type of query you want to do here. date类型不支持您要在此处执行的查询类型。

After lots of trail I found a solution.经过大量的跟踪,我找到了解决方案。

It's working for me.它对我有用。 Though I am not happy about it.虽然我对此并不高兴。

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "script": {
            "script": {
              "source": "doc['startTs'].value.hour * 60 + doc['startTs'].value.minute >= 0"
            }
          }
        },
        {
          "script": {
            "script": {
              "source": "doc['endTs'].value.hour * 60 + doc['endTs'].value.minute <= 45"
            }
          }
        }
      ]
    }
  }
}

Still looking for a better solution.仍在寻找更好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM