1

如何搜索介于开始时间和结束时间之间的文档?例如,我想仅使用“18:33”或“21:32”之类的时间查询以下文档。“18:33”将返回以下文档,而“21:32”则不会。我不在乎日期部分或秒。

{
  "my start time field": "2020-01-23T18:32:21.768Z",
  "my end time field": "2020-01-23T20:32:21.768Z"
}

我已查看:使用字段range查询。date但我不确定如何只看时间。另外,我想查看时间是否在两个字段之间,而不是字段是否在两次之间。


本质上,Elasticsearch 相当于BETWEENSQL Server。 喜欢这个答案,除了我不想使用当前时间而是一个变量。

DECLARE @blah datetime2 = GETDATE()

SELECT  *
FROM Table1 T
WHERE CAST(@blah AS TIME) 
      BETWEEN cast(T.StartDate as TIME) AND cast(T.EndDate as TIME)
4

3 回答 3

1

不要在基于此讨论的日期时间数据类型中存储时间。

如果您想过滤一天中的特定时间,您需要将其提取到它自己的字段中。

通过Kibana 开发工具 -> 控制台

创建一些模拟数据:

POST between-research/_doc/1
{
  "my start hour": 0,
  "my end hour": 12
}

POST between-research/_doc/2
{
  "my start hour": 13,
  "my end hour": 23
}

执行“之间”搜索

POST between-research/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "my start hour": {
              "lte": 10
            }
          }
        },
        {
          "range": {
            "my end hour": {
              "gte": 10
            }
          }
        }
      ]
    }
  }
}
于 2020-03-12T18:32:54.853 回答
1

解决方案 1:现有日期格式

在不单独更改和摄取您的小时和分钟的情况下,我提出了以下解决方案,我认为您不会对 ES 为您提供解决方案的方式感到满意,但它确实有效。

我根据您提供的数据创建了一个示例映射、文档、查询和响应。

映射:

PUT my_date_index
{
  "mappings": {
    "properties": {
      "start_time":{
        "type": "date",
        "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
      },
      "end_time":{
        "type": "date",
        "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
      }
    }
  }
}

样本文件:

POST my_date_index/_doc/1
{
  "start_time": "2020-01-23T18:32:21.768Z",
  "end_time": "2020-01-23T20:32:21.768Z"
}

POST my_date_index/_doc/2
{
  "start_time": "2020-01-23T19:32:21.768Z",
  "end_time": "2020-01-23T20:32:21.768Z"
}

POST my_date_index/_doc/3
{
  "start_time": "2020-01-23T21:32:21.768Z",
  "end_time": "2020-01-23T22:32:21.768Z"
}

查询请求:

POST my_date_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "script": {
            "script": {
              "source": """
                ZonedDateTime zstart_time = doc['start_time'].value;
                int zstart_hour = zstart_time.getHour();
                int zstart_minute = zstart_time.getMinute();
                int zstart_total_minutes = zstart_hour * 60 + zstart_minute;

                ZonedDateTime zend_time = doc['end_time'].value;
                int zend_hour = zend_time.getHour();
                int zend_minute = zend_time.getMinute();
                int zend_total_minutes = zend_hour * 60 + zend_minute;

                int my_input_total_minutes = params.my_input_hour * 60 + params.my_input_minute;

                if(zstart_total_minutes <= my_input_total_minutes && zend_total_minutes >= my_input_total_minutes){
                  return true;
                }

                return false;

              """,
              "params": {
                "my_input_hour": 20,
                "my_input_minute": 10
              }
            }
          }
        }
      ]
    }
  }
}

基本上

  • 计算分钟数start_date

  • 计算分钟数end_date

  • params.my_input_hour从&计算分钟数params.my_input_minute

  • start_date <= input <= end_date使用所有三个值的分钟执行 if 条件中的逻辑并相应地返回文档。

回复:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 2.0,
    "hits" : [
      {
        "_index" : "my_time_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 2.0,
        "_source" : {
          "start_time" : "18:32",
          "end_time" : "20:32"
        }
      }
    ]
  }
}

当涉及到解决方案 1 时,请彻底测试它们的性能问题,因为脚本查询通常会影响性能,但是如果您别无选择,它们会派上用场。

让我知道这是否有帮助!

于 2020-03-12T18:44:05.940 回答
1

根据 OP 的建议和他提供的符合 stackoverflow 法则的链接,我在这里提供了第二个解决方案:

解决方案 2:将小时分钟的单独字段插入为 hh:mm

请注意使用的格式,即hour_minute. 您可以在上述链接下找到可用的格式列表。

基本上,您使用单独的字段重新摄取文档,该字段将具有hour and minute values并执行range queries以获得您想要的内容。

映射:

PUT my_time_index
{
  "mappings": {
    "properties": {
      "start_time":{
        "type": "date",
        "format": "hour_minute"
      },
      "end_time":{
        "type": "date",
        "format": "hour_minute"
      }
    }
  }
}

样本文件:

POST my_time_index/_doc/1
{
  "start_time": "18:32",
  "end_time": "20:32"
}

查询请求:

POST my_time_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "start_time": {
              "gte": "18:00"
            }
          }
        },
        {
          "range": {
            "end_time": {
              "lte": "21:00"
            }
          }
        }
      ]
    }
  }
}

让我知道这是否有帮助!

于 2020-03-27T07:05:18.850 回答