关于Elasticsearch:Elasticsearch – 查询没有指定时区的日期

Elasticsearch - query dates without a specified timezone

我有一个索引与以下映射 - 日期的标准格式。 在下面的第二条记录中,指定的时间实际上是当地时间 - 但ES将其视为UTC。

即使ES在内部将所有已解析的日期时间转换为UTC,但它显然也必须存储原始字符串。

我的问题是,是否(以及如何)查询scheduleDT值没有明确指定时区的所有记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
  "curator_v3": {
     "mappings": {
        "published": {
           "analyzer":"classic",
           "numeric_detection": true,
           "properties": {
              "Id": {
                 "type":"string",
                 "index":"not_analyzed",
                 "include_in_all": false
               },
              "createDT": {
                 "type":"date",
                 "format":"dateOptionalTime",
                 "include_in_all": false
               },
              "scheduleDT": {
                 "type":"date",
                 "format":"dateOptionalTime",
                 "include_in_all": false
               },
              "title": {
                 "type":"string",
                 "fields": {
                    "english": {
                       "type":"string",
                       "analyzer":"english"
                     },
                    "raw": {
                       "type":"string",
                       "index":"not_analyzed"
                     },
                    "shingle": {
                       "type":"string",
                       "analyzer":"shingle"
                     },
                    "spanish": {
                       "type":"string",
                       "analyzer":"spanish"
                     }
                  },
                 "include_in_all": false
               }
            }
         }
      }
   }
}

我们使用.NET作为ElasticSearch的客户端,并且在为scheduleDT字段指定时区时并不一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{
  "took": 2,
  "timed_out": false,
  "_shards": {
     "total": 12,
     "successful": 12,
     "failed": 0
   },
  "hits": {
     "total": 32,
     "max_score": null,
     "hits": [
         {
           "_index":"curator_v3",
           "_type":"published",
           "_id":"29651227",
           "_score": null,
           "fields": {
              "Id": [
                 "29651227"
               ],
              "scheduleDT": [
                 "2015-11-21T22:17:51.0946798-06:00"
               ],
              "title": [
                 "97 Year-Old Woman Cries Tears Of Joy After Finally Getting Her High School Diploma"
               ],
              "createDT": [
                 "2015-11-21T22:13:32.3597142-06:00"
               ]
            },
           "sort": [
               1448165871094
            ]
         },
         {
           "_index":"curator_v3",
           "_type":"published",
           "_id":"210466413",
           "_score": null,
           "fields": {
              "Id": [
                 "210466413"
               ],
              "scheduleDT": [
                 "2015-11-22T12:00:00"
               ],
              "title": [
                 "6 KC treats to bring to Thanksgiving"
               ],
              "createDT": [
                 "2015-11-20T15:08:25.4282-06:00"
               ]
            },
           "sort": [
               1448193600000
            ]
         }
      ]
   },
  "aggregations": {
     "ScheduleDT": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 27,
        "buckets": [
            {
              "key": 1448165871094,
              "key_as_string":"2015-11-22T04:17:51.094Z",
              "doc_count": 1
            },
            {
              "key": 1448193600000,
              "key_as_string":"2015-11-22T12:00:00.000Z",
              "doc_count": 4
            }
         ]
      }
   }
}

您可以通过查询字段长度小于20个字符(例如2015-11-22T12:00:00)的scheduleDT的文档来完成此操作。 具有指定时区的所有日期字段都会更长。

这样的事情应该做:

1
2
3
4
5
6
7
8
9
10
11
{
 "query": {
   "filtered": {
     "filter": {
       "script": {
         "script":"doc.scheduleDT.value.size() < 20"
        }
      }
    }
  }
}

但请注意,为了使您的查询更容易创建,您应该始终尝试在索引文档之前转换所有UTC时间戳。

最后,还要确保已启用动态脚本以运行上述查询。

UPDATE

实际上,如果您在脚本中直接使用_source,它将起作用,因为它将从文档索引时返回源中的实际值:

1
2
3
4
5
6
7
8
9
10
11
{
 "query": {
   "filtered": {
     "filter": {
       "script": {
         "script":"_source.scheduleDT.size() < 20"
        }
      }
    }
  }
}