Elasticsearch: фильтр по условиям в сгруппированных документах

#database #elasticsearch #filter #aggregation

#База данных #elasticsearch #Фильтр #агрегация

Вопрос:

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

Пример моих данных:

 proc_id event   timestamp
1       ON      1000
1       EV1     1001
2       ON      1002
1       OFF     1003
3       ON      1004
2       EV2     1005
3       EV1     1006
3       EV_END  1007
2       EV_END  1008
  

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

Я видел, что с версии 2.x есть bucket_selectors и скрипты, но я не понимаю идею.

Псевдозапрос с тем, что я хочу сделать:

 curl -XPOST 'localhost:9200/proc/_search?pretty' -d '
{
    "query": { "match_all": {} },
    "aggs": {
        "group_by_proc_id": {
            "terms": {
             "field": "proc_id",
             **ONLY if proc has at least one trace with event == 'EV_END'**
            }
        }
    }
}'
  

Комментарии:

1. не могли бы вы предоставить желаемый результат для опубликованных вами образцов данных?

2. Это не совсем результат, но «псевдозапрос» показывает идею

3. Помогло ли решение?

Ответ №1:

Я думаю, вы могли бы использовать агрегацию фильтров для получения идентификаторов proc_id, где присутствует событие EV_END.

 {
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "EV_END": {
      "filter": {
        "term": {
          "event": "EV_END"
        }
      },
      "aggs": {
        "proc_group": {
          "terms": {
            "field": "proc_id",
            "size": 10
          }
        }
      }
    }
  }
}