0

У меня есть документы типа:Elasticsearch Aggregation на день недели и час дня

[{"msg":"hello", date: "some-date"},{"msg":"hi!", date: "some-date"}, ... 

Я хочу, чтобы иметь количество документов по дням недели. Например, x сообщений отправили в понедельник, а y были отправлены во вторник и так далее.

Я использовал date_histogram с агрегацией, но он возвращает мне документы день мудрым. Он возвращает мне день, но скажите «Wed, 22» и «Wed, 29» возвращаются как отдельные агрегирующие документы.

Это несколько связано с Elasticsearch - group by day of week and hour, но ответа на этот вопрос нет, поэтому я отправляю его повторно. Согласно предложению, он просит меня выполнить агрегирование термина на key_as_string, но мне нужно добавить doc_count для каждого объекта, а не просто считать термины. Я также не знаю, как использовать key_as_string во вложенной агрегации.

Это то, что я пробовал:

"aggs" : { 
       "posts_over_days" : { 
        "date_histogram" : { 
         "field" : "created_time", 
         "interval": "day", 
         "format": "E" 
        } 
       } 
+1

Возможно, вы захотите включить агрегацию, которую вы пытались. – progrrammer

+0

Я включил агрегацию. Это то же самое, что и ответ в ссылке, которую я разместил. –

ответ

3

Та же проблема была решена в this thread.

Адаптирования решения вашей проблемы, нам нужно сделать скрипт, чтобы преобразовать дату в час дня и день недели:

Date date = new Date(doc['created_time'].value) ; 
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat('EEE, HH'); 
format.format(date) 

И использовать его в запросе:

{ 
    "aggs": { 
     "perWeekDay": { 
      "terms": { 
       "script": "Date date = new Date(doc['created_time'].value) ;java.text.SimpleDateFormat format = new java.text.SimpleDateFormat('EEE, HH');format.format(date)" 
      } 
     } 
    } 
} 
+0

Блестящий .. хотя я хочу, чтобы вещи (часы и дни) по-другому, но это довольно легко! :) И я как раз собирался публиковать и отвечать на это, принимая информацию из http://stackoverflow.com/questions/25492558/elasticsearch-get-time-in-groovy-script Но ваш скрипт отлично работает без каких-либо изменений. Я бы просто дал еще 15 минут, чтобы немного сократить его. Спасибо большое! –

+0

Будьте осторожны со сценарием, хотя, если у вас меньше данных, тогда все в порядке, но если у вас есть 100k данных, то у него есть значительная потеря производительности. Возможно, вы просто захотите провести синтаксический анализ в своем приложении после возврата результата. – progrrammer

1

Самый простой способ будет определять специальный день-неделю поле, которое удерживает только день недели для каждого документа, а затем сделать terms aggregation на это поле.

Если по какой-либо причине вы не хотите этого делать (или не можете), вот хак, который может помочь вам получить то, что вы хотите. Основная идея состоит в том, чтобы определить подполе "date.raw", которое является строкой, проанализировано с помощью standard analyzer, так что условия создаются для каждого дня недели. Затем вы можете агрегировать на этих условиях, чтобы получить свои счета, используя include, чтобы включать только те условия, которые вы хотите.

Вот отображение я использовал для тестирования:

PUT /test_index 
{ 
    "settings": { 
     "number_of_shards": 1 
    }, 
    "mappings": { 
     "doc": { 
     "properties": { 
      "msg": { 
       "type": "string" 
      }, 
      "date": { 
       "type": "date", 
       "format": "E, dd MMM yyyy", 
       "fields": { 
        "raw": { 
        "type": "string" 
        } 
       } 
      } 
     } 
     } 
    } 
} 

и несколько образцов документы:

POST /test_index/_bulk 
{"index":{"_index":"test_index","_type":"doc","_id":1}} 
{"msg": "hello","date": "Wed, 11 Mar 2015"} 
{"index":{"_index":"test_index","_type":"doc","_id":2}} 
{"msg": "hello","date": "Tue, 10 Mar 2015"} 
{"index":{"_index":"test_index","_type":"doc","_id":3}} 
{"msg": "hello","date": "Mon, 09 Mar 2015"} 
{"index":{"_index":"test_index","_type":"doc","_id":4}} 
{"msg": "hello","date": "Wed, 04 Mar 2015"} 

и агрегация и результаты:

POST /test_index/_search?search_type=count 
{ 
    "aggs":{ 
     "docs_by_day":{ 
      "terms":{ 
       "field": "date.raw", 
       "include": "mon|tue|wed|thu|fri|sat|sun" 
      } 
     } 
    } 
} 
... 
{ 
    "took": 2, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 4, 
     "max_score": 0, 
     "hits": [] 
    }, 
    "aggregations": { 
     "docs_by_day": { 
     "buckets": [ 
      { 
       "key": "wed", 
       "doc_count": 2 
      }, 
      { 
       "key": "mon", 
       "doc_count": 1 
      }, 
      { 
       "key": "tue", 
       "doc_count": 1 
      } 
     ] 
     } 
    } 
} 

Вот код все вместе:

http://sense.qbox.io/gist/0292ddf8a97b2d96bd234b787c7863a4bffb14c5

2

Re-сообщение от моего ответа здесь: https://stackoverflow.com/a/31851896/6247

ли эта помощь:

"aggregations": { 
    "timeslice": { 
     "histogram": { 
      "script": "doc['timestamp'].date.getHourOfDay()", 
      "interval": 1, 
      "min_doc_count": 0, 
      "extended_bounds": { 
       "min": 0, 
       "max": 23 
      }, 
      "order": { 
       "_key": "desc" 
      } 
     } 
    } 

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

Вы можете использовать 'getDayOfWeek', 'getHourOfDay', ... (см. «Время Joda» для более).

Это замечательно в течение нескольких часов, но в течение нескольких дней/месяцев оно даст вам номер, а не название месяца. Чтобы обойти, вы можете получить временной интервал как строку - , но, это не будет работать с расширенным ограничением, поэтому у вас могут быть пустые результаты (т. Е. [Mon, Вт, Fri, Sun]).

В-случае, если вы хотите, что именно здесь:

"aggregations": { 
    "dayOfWeek": { 
     "terms": { 
      "script": "doc['timestamp'].date.dayOfWeek().getAsText()", 
      "order": { 
       "_term": "asc" 
      } 
     } 
    } 

Даже если это не поможет, надеюсь, кто-то найдет его и пользу от него.

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