2015-11-22 6 views
1

У меня есть индекс со следующими отображениями - стандартный формат для даты. Во второй записи ниже указанное время фактически является местным временем, но ES рассматривает его как UTC.Elasticsearch - даты запроса без указанного часового пояса

Несмотря на то, что ES внутренне преобразует все разобранные даты в UTC, но, очевидно, оно также должно хранить исходную строку.

Мой вопрос в том, может ли (и как) возможно запросить все записи, для которых значение scheduleDT не имеет явно заданного часового пояса.

{ 
    "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.

{ 
    "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 
      } 
     ] 
     } 
    } 
} 

ответ

2

Вы можете сделать это, запрашивая документ, имеющий scheduleDT поле, длина которого меньше, чем 20 символов (например, 2015-11-22T12:00:00). Все поля даты с указанным часовым поясом будут длиннее.

Что-то вроде этого нужно сделать:

{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "script": { 
      "script": "doc.scheduleDT.value.size() < 20" 
     } 
     } 
    } 
    } 
} 

Заметим, однако, что для того, чтобы сделать ваши запросы легче создавать, вы всегда должны пытаться конвертировать все ваши временные метки в формате UTC перед тем индексировать документы.

И наконец, убедитесь, что у вас есть dynamic scripting enabled, чтобы выполнить вышеуказанный запрос.

UPDATE

На самом деле, если вы используете _source непосредственно в сценарии он будет работать, потому что он будет возвращать реальное значение из источника, как это было, когда документ был проиндексирован:

{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "script": { 
      "script": "_source.scheduleDT.size() < 20" 
     } 
     } 
    } 
    } 
} 
+0

Brillant Val. Не рассматривал обработку значения как строку. Мне пришлось немного изменить ваш сценарий: doc.scheduleDT.value.toString(). Size() <20 – ShawnMac

+0

О, вы правы, извините, что, рад, что вы это поняли. – Val

+0

У меня было достаточно данных для преобразования, поэтому я не сразу заметил это, но «значение», сравнимое с 20 символами, похоже, является основным представлением даты (например, 1448320714367), а не эквивалентом строки (т.е. 2015-11-23T17: 18: 34.367949-06: 00)-06: 00) Я пробовал различные способы вернуть то же строковое представление, отображаемое в результатах, и использовать его для проверки длины - но пока не нашел способа сделать это. – ShawnMac

Смежные вопросы