2014-09-02 3 views
0

Я хочу рассчитать разницу вложенных агрегатов между двумя датами .Как рассчитать разницу между метриками в разных скоплениях в elasticsearch

Чтобы быть более конкретным, можно рассчитать разницу между date_1.buckets.field_1.buckets.field_2.buckets.field_3.value - date_2.buckets.field_1.buckets.field_2.buckets.field_3.value с учетом следующего запроса/ответа. Возможно ли это с помощью elasticsearch v.1.0.1?

запрос запрос

агрегация выглядит следующим образом:

{ 
    "query": { 
    "filtered": { 
     "query": { 
     "match_all": {} 
     }, 
     "filter": { 
     "bool": { 
      "must": [ 
      { 
       "terms": { 
       "date": [ 
        "2014-08-18 00:00:00.0", 
        "2014-08-15 00:00:00.0" 
       ] 
       } 
      } 
      ] 
     } 
     } 
    } 
    }, 
    "aggs": { 
    "date_1": { 
     "filter": { 
     "terms": { 
      "date": [ 
      "2014-08-18 00:00:00.0" 
      ] 
     } 
     }, 
     "aggs": { 
     "my_agg_1": { 
      "terms": { 
      "field": "field_1", 
      "size": 2147483647, 
      "order": { 
       "_term": "desc" 
      } 
      }, 
      "aggs": { 
      "my_agg_2": { 
       "terms": { 
       "field": "field_2", 
       "size": 2147483647, 
       "order": { 
        "_term": "desc" 
       } 
       }, 
       "aggs": { 
       "my_agg_3": { 
        "sum": { 
        "field": "field_3" 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    }, 
    "date_2": { 
     "filter": { 
     "terms": { 
      "date": [ 
      "2014-08-15 00:00:00.0" 
      ] 
     } 
     }, 
     "aggs": { 
     "my_agg_1": { 
      "terms": { 
      "field": "field_1", 
      "size": 2147483647, 
      "order": { 
       "_term": "desc" 
      } 
      }, 
      "aggs": { 
      "my_agg_1": { 
       "terms": { 
       "field": "field_2", 
       "size": 2147483647, 
       "order": { 
        "_term": "desc" 
       } 
       }, 
       "aggs": { 
       "my_agg_3": { 
        "sum": { 
        "field": "field_3" 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

И ответ выглядит следующим образом:

{ 
    "took": 236, 
    "timed_out": false, 
    "_shards": { 
    "total": 1, 
    "successful": 1, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 1646, 
    "max_score": 0, 
    "hits": [] 
    }, 
    "aggregations": { 
    "date_1": { 
     "doc_count": 823, 
     "field_1": { 
     "buckets": [ 
      { 
      "key": "field_1_key_1", 
      "doc_count": 719, 
      "field_2": { 
       "buckets": [ 
       { 
        "key": "key_1", 
        "doc_count": 275, 
        "field_3": { 
        "value": 100 
        } 
       } 
       ] 
      } 
      } 
     ] 
     } 
    }, 
    "date_2": { 
     "doc_count": 823, 
     "field_1": { 
     "buckets": [ 
      { 
      "key": "field_1_key_1", 
      "doc_count": 719, 
      "field_2": { 
       "buckets": [ 
       { 
        "key": "key_1", 
        "doc_count": 275, 
        "field_3": { 
        "value": 80 
        } 
       } 
       ] 
      } 
      } 
     ] 
     } 
    } 
    } 
} 

Спасибо.

+0

Я не уверен, если это возможно в новой версии, но я должен был справиться с этим вручную после того, как будет получен ответ in es 1.1.0. [сборка elasticsearch для сортировки по коэффициенту агрегации] (http://stackoverflow.com/q/24624371/432903) – prayagupd

+0

@PrayagUpd Мне, возможно, придется обрабатывать его на стороне клиента. Мне интересно, можно ли это сделать в elasticsearch с версией, которую я запускаю. Возможно, это возможно в будущем с [агрегацией с использованием сценариев] (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-scripted-metric-aggregation.html) (ES 1.4.0) – gdiamantidis

+0

Возможно, это может исправить, но эта функция сама по себе экспериментальна для 1.4.0. Мне пришлось обрабатывать это вручную в тысячах документов для 3/4 функций в приложении для аналитики.Надеюсь, что он встроен в ближайшие версии. – prayagupd

ответ

1

Арифметические операции разрешены между результатом двух агрегатов из elasticsearch DSL, даже с использованием сценариев. (Upto версия 1.1.1, по крайней мере, я знаю)

Такие операции необходимо обрабатывать на стороне клиента после обработки результата aggs.

Ссылка

elasticsearch aggregation to sort by ratio of aggregations

0

В 1.0.1 я не мог найти ничего, но в 1.4.2, вы можете попробовать scripted_metric агрегацию (пока экспериментальный).

Вот scripted_metric documentation page

Я не хорошо с синтаксисом elasticsearch, но я думаю, что ваши метрические входы будут:

init_script - просто инициализировать аккумулятор для каждой даты:

"init_script": "_agg.d1Val = 0; _agg.d2Val = 0;" 

map_script - проверьте дату документа и добавьте в правый аккумулятор:

"map_script": "if (doc.date == firstDate) { _agg.d1Val += doc.field_3; } else { _agg.d2Val = doc.field_3;};", 

reduce_script - накапливаются промежуточные данные из различных осколков и вернуть окончательные результаты:

"reduce_script": "totalD1 = 0; totalD2 = 0; for (agg in _aggs) { totalD1 += agg.d1Val ; totalD2 += agg.d2Val ;}; return totalD1 - totalD2" 

Я не думаю, что в этом случае вам нужен combine_script.

Если, конечно, если вы не можете использовать 1.4.2, чем это не поможет :-)

+0

спасибо за ответ. Я также нашел scripted_metric, но не могу использовать эту версию, и она все еще экспериментальна. – gdiamantidis

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