2016-09-29 3 views
0

В моем индексе у меня есть документы, в которых каждый документ имеет отметку времени (через поле «datetime») в формате yyyy-MM-dd'THH: mm: ssElasticsearch: добавление диапазона фильтра к каждому ведру в гистограмме даты

У меня есть запрос, который содержит ведра ежедневных (даты гистограммы) средних значений для данного поля в документе, это хорошо работает, никаких проблем.

Я пытаюсь расширить это, чтобы фильтровать каждое ведро так, чтобы среднесуточный режим учитывал только временные метки в пределах определенной части каждого дня (например, только документы, созданные утром или днем ​​и т. Д.).

Я пробовал следующий запрос:

{ 
    "size": 0, 
    "aggs": { 
     "rating": { 
     "date_histogram": { 
      "field": "datetime", 
      "interval": "1d", 
      "time_zone": "Europe/London", 
      "min_doc_count": 1 
     }, 
     "aggs": { 
      "afternoon": { 
       "filter": { 
        "range": { 
        "datetime": { 
         "gte": "12:00:00", 
         "lte": "17:00:00", 
         "format": "HH:mm:ss" 
        } 
        } 
       }, 
       "aggs": { 
        "service": { 
        "avg": { 
         "field": "qr2" 
        } 
        } 
       } 
      } 
     } 
     } 
    }, 
    "query": { 
     "constant_score": { 
     "filter": { 
      "range": { 
       "datetime": { 
        "gte": "2016-08-28T23:00:00", 
        "lte": "2016-09-29T07:34:49" 
       } 
      } 
     } 
     } 
    } 
} 

Но это возвращает нулевые значения для агрегации (граф 0 дока), даже если родительские ведра имеют несколько документов с временными метками, которые попадают в диапазон времени - см пример ниже:

"aggregations": { 
     "rating": { 
     "buckets": [ 
      { 
       "key_as_string": "1472428800000", 
       "key": 1472425200000, 
       "doc_count": 843, 
       "afternoon": { 
        "doc_count": 0, 
        "service": { 
        "value": null 
        } 
       } 
      }, 
      { 
       "key_as_string": "1472515200000", 
       "key": 1472511600000, 
       "doc_count": 748, 
       "afternoon": { 
        "doc_count": 0, 
        "service": { 
        "value": null 
        } 
       } 
      }, 

Я предполагаю, что только с указанием времени части DateTime не имея желаемый эффект, это, вероятно, делает запрос диапазона с датой частью дефолте до некоторого значения, следовательно, не соответствующий какому-либо временных меток для документов, возвращенных в e parent bucket.

Есть ли простой способ, которым я могу это сделать или мне нужно разделить время на отдельное поле?

Любая помощь очень ценится!

ответ

1

выше ответ работает отлично. Но для версий до 2.1.0 это работает

{ 
    "script": { 
     "script": "def hod = doc.datetime.date.getHourOfDay(); return hod >= min && hod <= max", 
     "params": { 
      "min": 12, 
      "max": 17 
     } 
    } 
} 

Это связано с проблемой старых версий и исправлена. https://github.com/elastic/elasticsearch-net/issues/1931

3

Существует два пути.

Первым решением является индексирование другого поля, называемого hourOfTheDay, так что вы можете запустить простой цифровой фильтр range.

  "filter": { 
       "range": { 
       "hourOfTheDay": { 
        "gte": 12, 
        "lte": 17 
       } 
       } 
      }, 

Второе решение просто включает в себя использование Groovy сценариев в script фильтр

  "filter": { 
       "script": { 
       "script": { 
        "inline": "def hod = doc.datetime.date.getHourOfDay(); return hod >= min && hod <= max", 
        "params": { 
         "min": 12, 
         "max": 17 
        } 
       } 
       } 
      }, 

Для этого второго решения, убедитесь, что вы enable dynamic scripting

+0

Спасибо. Похоже, мне нужно добавить поле времени, поскольку мы не хотим включать динамические сценарии. – InTooDeep

+0

Прохладный, рад, что это помогло! – Val

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