Одинаковая агрегация по нескольким метрикам
Я настроил снегоочиститель с 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"
}
}
}
}
}
}
}
}
}
}
}
Теперь для каждого ежедневного сегмента вы получите два вложенных сегмента: один для количества просмотров страниц, а другой для количества кликов.