Elasticsearch: объединение документов по диапазону дат

У меня есть набор документов в ElasticSearch 5.5 с двумя полями даты: start_date и end_date. Я хочу объединить их в сегменты гистограммы даты (например, еженедельно), чтобы, если start_date ‹ неделя X ‹ end_date, документ находился в сегменте «неделя X». Это означает, что один документ может находиться в нескольких корзинах.

Рассмотрим следующий конкретный пример: у меня есть набор документов, описывающих сотрудников компании, и для каждого сотрудника у вас есть дата приема на работу и (необязательно) дата увольнения. Я хочу построить гистограмму числа активных сотрудников за последние двенадцать месяцев.

Пример содержимого документа:

{
   "start_date": "2013-01-12T00:00:00.000Z",
   "end_date": "2016-12-08T00:00:00.000Z",
   "id": "123123123"
}

Есть ли способ сделать это в ES?


person Tofig Hasanov    schedule 02.08.2017    source источник
comment
всегда подкрепляйте свои вопросы правильным json, чтобы показать пример использования. спасибо   -  person user3775217    schedule 02.08.2017
comment
Добавил один, хотя не кажется, что он добавляет большую ценность   -  person Tofig Hasanov    schedule 02.08.2017
comment
дело не в ценности, а в том, что когда я прочитаю сообщение, я смогу лучше визуализировать вашу проблему, и, очевидно, нажатие отформатированного json не сильно повредит.   -  person user3775217    schedule 02.08.2017
comment
Я сомневаюсь, что один документ может появиться в нескольких корзинах одной агрегации. Я могу предложить проверить скрипты для агрегирования дат, с помощью агрегаций каналов и для денормализации данные, например предварительно вычислить все недели между start_date и end_date и сохранить их в виде списка в поле active_weeks.   -  person Nikolay Vasiliev    schedule 03.08.2017
comment
@NikolayVasiliev Я нашел один способ сделать это (проверьте мой ответ), но я все еще не доволен этим. Возможно, сценарии — лучший путь вперед   -  person Tofig Hasanov    schedule 03.08.2017


Ответы (2)


Я нашел один способ сделать это, используя агрегацию фильтров ( https://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-bucket-filter-aggregation.html). Если мне нужен, скажем, отчет за 12 последних месяцев, я бы создал 12 сегментов, где каждый сегмент определяет условия фильтрации, такие как:

"bool":{
 "must":[{
  "range":{
   "start_date":{
    "lte":"2016-01-01T00:00:00.000Z"
   }
  }
 },{
 {
  "range":{
   "end_date":{
    "gt":"2016-02-01T00:00:00.000Z"
   }
  }
 }]
}

Тем не менее, я считаю, что было бы неплохо, если бы был более простой способ сделать это, поскольку, если я хочу сказать, что конечные 365 дней, это означает, что мне нужно создать фильтры 365 сегментов, что делает результирующий запрос очень большим.

person Tofig Hasanov    schedule 03.08.2017

Я знаю, что этот вопрос довольно старый, но, поскольку он все еще открыт, я делюсь своими знаниями об этом. Также в этом вопросе четко не объясняется, какой результат ожидается, но все же я думаю, что этого можно достичь с помощью «Агрегации гистограммы дат» и «Агрегации скриптов ведра».

Вот ссылки на документацию для обеих этих агрегаций.

https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-aggregations-bucket-datehistogram-aggregation.html

https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-aggregations-pipeline-bucket-script-aggregation.html

person Surbhi Harsh    schedule 11.06.2019
comment
Пожалуйста, добавьте краткое содержание ваших ссылок в свой ответ. - person mastisa; 11.06.2019
comment
Ссылки должны быть в состоянии описать вам все. И если вы хотите, чтобы я предоставил пример запроса по этому поводу, мне понадобится ожидаемый формат результата. - person Surbhi Harsh; 11.06.2019