Одинаковая агрегация по нескольким метрикам

У меня есть настройки снегоочиститель с Elasticsearch.

Когда я хочу получить данные, я просто делаю обычные запросы и использую агрегаты, чтобы получить их по дням, странам и т. Д.

Итак, я хочу выяснить рейтинг кликов для этих агрегатов, у меня есть 2 вида событий: просмотры страниц и клики.

В настоящее время я делаю 2 запроса:

Просмотры страниц:

{
"size": 0,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"event": "page_view"}
}
],
"must_not": {
"term": {
"br_family": "Robot"}
}
}
}
}
},
"aggs": {
"dates": {
"date_histogram": {
"field": "collector_tstamp",
"interval": "day"}
}
}
}

Просмотры:

{
"size": 0,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"event": "struct"}
},
{
"term": {
"se_action": "click"}
}
],
"must_not": {
"term": {
"br_family": "Robot"}
}
}
}
}
},
"aggs": {
"dates": {
"date_histogram": {
"field": "collector_tstamp",
"interval": "day"}
}
}
}

Я форматирую ответ на что-то более простое в использовании и затем объединяю их в PHP, используя что-то вроде этого.

function merge_metrics($pv,$c){
$r = array();

if(count($pv) > 0){
foreach ($pv as $key => $value) {
$r[$value['name']]['page_views'] += $value['count'];
}
}
if(count($c) > 0){
foreach ($c as $key => $value) {
$r[$value['name']]['clicks'] += $value['count'];
}
}

$rf = array();

foreach ($r as $key => $value) {
$tmp_clicks = isset($value['clicks']) ? $value['clicks'] : 0;
$tmp_page_views = isset($value['page_views']) ? isset($value['page_views']) : 0;
$rf[] = array(
'name' => $key,
'page_views' => $tmp_page_views,
'clicks' => $tmp_clicks,
'ctr' => ctr($tmp_clicks,$tmp_page_views)
);
}

return $rf;
}

И $ pv, и $ c являются массивами, которые содержат агрегаты, полученные в результате запросов к Elasticsearch, и я делаю некоторое форматирование для простоты использования.

Мой вопрос:

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

{
"data": [
{
"day": "2015-10-13",
"page_views": 61,
"clicks": 0,
},
{
"day": "2015-10-14",
"page_views": 135,
"clicks": 1,
},
{
"day": "2015-10-15",
"page_views": 39,
"clicks": 0,
}
]
}

Но без меня, чтобы вручную объединить их?

1

Решение

Да, это определенно возможно, если вы объедините свои агрегаты в один запрос. Например, я полагаю, у вас есть один запрос для просмотра страниц:

{
"query": {...}
"aggregations": {
"by_day": {
"date_histogram": {
"field": "day",
"interval": "day"},
"aggs": {
"page_views_per_day": {
"sum": {
"field": "page_views"}
}
}
}
}
}

И еще один запрос на клики:

{
"query": {...}
"aggregations": {
"by_day": {
"date_histogram": {
"field": "day",
"interval": "day"},
"aggs": {
"clicks_per_day": {
"sum": {
"field": "clicks"}
}
}
}
}
}

Если у вас есть те же ограничения в вашем queryвы можете объединить их вместе на date_histogram уровень, как это:

{
"query": {...}
"aggregations": {
"by_day": {
"date_histogram": {
"field": "day",
"interval": "day"},
"aggs": {
"page_views_per_day": {
"sum": {
"field": "page_views"}
},
"clicks_per_day": {
"sum": {
"field": "clicks"}
}
}
}
}
}

ОБНОВИТЬ

Поскольку ваши запросы различны для каждого из ваших агрегатов, мы должны сделать это немного по-другому, т. Е. С помощью дополнительного filters агрегация, как это:

{
"size": 0,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"terms": {
"event": [
"page_view",
"struct"]
}
}
],
"should": {
"term": {
"se_action": "click"}
},
"must_not": {
"term": {
"br_family": "Robot"}
}
}
}
}
},
"aggs": {
"dates": {
"date_histogram": {
"field": "collector_tstamp",
"interval": "day"},
"aggs": {
"my_filters": {
"filters": {
"filters": {
"page_views_filter": {
"bool": {
"must": [
{
"term": {
"event": "page_view"}
}
],
"must_not": {
"term": {
"br_family": "Robot"}
}
}
},
"clicks_filter": {
"bool": {
"must": [
{
"term": {
"event": "struct"}
},
{
"term": {
"se_action": "click"}
}
],
"must_not": {
"term": {
"br_family": "Robot"}
}
}
}
}
}
}
}
}
}
}

Теперь для каждого ежедневного сегмента вы получите два вложенных сегмента: один для количества просмотров страниц, а другой для количества кликов.

2

Другие решения

Других решений пока нет …