Blog

2015.01.22 - 번역 - Intro to Aggregations pt. 2: Sub-Aggregations

drscg 2019. 1. 6. 17:11

Welcome Back! Last time on Intro to Aggregations, we explored the basic concepts of aggregations and how to start using them. We toyed with simple bucket and metric aggregations, which gave us simple analytics.

지난 번에 Intro to Aggregations에서, aggregation의 기본 개념과 사용방법을 살펴보았다. 간단한 bucket과 metric을 다루었는데, 이는 간단한 analytic을 제공했다.

Today, we are going to learn about sub-aggregations. The most powerful feature of aggregations in Elasticsearch is the ability to embed aggregations (both buckets and metrics) inside…wait for it…other aggregations. Sub-aggregations allow you to continuously refine and separate groups of criteria of interest, then apply metrics at various levels in the aggregation hierarchy to generate your report.

오늘, sub-aggregation에 대하여 살펴볼 것이다. Elasticsearch의 aggregation에서 가장 강력한 기능은 다른 aggregation 내부에 aggregation(bucket과 metric 모두)을 포함할 수 있는 능력이다. sub-aggregation을 사용하면, 관심 기준 그룹을 정제하고 분리한 다음, aggregation의 다양한 level에서 metric을 적용하여 report를 생성할 수 있다.

The first approach we will look at involves embedding buckets inside of other buckets. If we take our first example from last week about the Five Boroughs, we can embed an additional bucket underneath to determine the top three incident contributing factors in each borough:

우리가 살펴볼 첫번째 방법은 다른 bucket 내부에 bucket을 넣는 것이다. 지난 주의 5개 자치구에 대한 첫번째 예를 보면, 각 자치구의 상위 3대 사고 기여 원인을 결정하기 위하여, 추가적인 bucket을 아래에 넣을 수 있다.

GET /nyc_visionzero/_search?search_type=count
{
 
"aggs" : {
 
"all_boroughs": {
   
"terms": {
   
"field": "borough"
   
},
   
"aggs": {
   
"cause": {
     
"terms": {
     
"field": "contributing_factor_vehicle",
     
"size": 3
     
}
   
}
   
}
 
}
 
}
}

In this aggregation, the original “all_boroughs” aggregation remains unchanged. There is a new “aggs” element that has been added as a JSON sibling to “terms” (i.e., on the same level in the JSON tree). The new element tells Elasticsearch to begin a sub-aggregation. Inside the new “aggs” element, we name our new sub-aggregation (“cause”) and use another terms bucket. This bucket’s criteria is the contributing factor field, limited to 3 results.

이 aggregation에서, 원래의 “all_boroughs” aggregation은 변경없이 그대로이다. “terms”와 형제(JSON tree에서 동등한 level)로 JSON으로 추가된 새로운 "aggs" 요소가 있다. 새로운 요소는 Elasticsearch에서 sub-aggregation의 시작을 지시한다. 새로운 "aggs" 요소 내부에, 새로운 sub-aggregation의 이름 (“cause”)을 지정하고 또다른 terms bucket을 사용한다. 3개의 결과로 제한된 이 bucket의 기준은 기여 원인 field이다.

The response looks like this (truncated):

response는 다음과 같다.

{
 
"took": 29,
 
"aggregations": {
   
"all_boroughs": {
     
"buckets": [
     
{
       
"key": "BROOKLYN",
       
"doc_count": 86549,
       
"cause": {
         
"buckets": [
           
{
           
"key": "Unspecified",
           
"doc_count": 57203
           
},
           
{
           
"key": "Driver Inattention/Distraction",
           
"doc_count": 6954
           
},
           
{
           
"key": "Failure to Yield Right-of-Way",
           
"doc_count": 4209
           
}
         
]
       
}
     
},
     
...

Now you can see that we have our original aggregation data. We see again that Brooklyn has over 86,000 traffic incidents. But now it’s been enriched with the top three causes (“Unspecified”, “Inattention”, and “Failure to yield”) and the results of these newly added bucket are embedded under the results of the old bucket. If you were to run this example, you would see that similar data has enriched the rest of the boroughs as well, since the sub-aggregation runs for every bucket generated by the parent.

이제, 원래의 aggregation data를 가지고 있음을 알 수 있다. Brooklyn은 86,000 이상의 교통사고가 있음을 다시 알 수 있다. 그러나 이제 상위 3가지 원인이 추가되어, 이들 새로 추가된 bucket의 결과가 기존 bucket 결과의 아래에 포함된다. 이 예제를 실행하면, 부모에 의해 생성된 모든 bucket에 대해 sub-aggregation을 실행하므로, 나머지 자치구들 또한 유사한 데이터를 볼 수 있을 것이다.

And this being Elasticsearch, we can embed as much as we want. You could, for example, find out how many incidents occurred per-month, per-cause, per-borough:

그리고, 이것은 Elasticsearch이기 대문에, 원하는 만큼 많이 넣을 수 있다. 예를 들어, 월별, 원인별, 자치구별 사고의 수를 확인할 수 있다.

GET /nyc_visionzero/_search?search_type=count
{
 
"aggs" : {
 
"all_boroughs": {
   
"terms": {
   
"field": "borough"
   
},
   
"aggs": {
   
"cause": {
     
"terms": {
     
"field": "contributing_factor_vehicle",
     
"size": 3
     
},
     
"aggs": {
     
"incidents_per_month": {
       
"date_histogram": {
       
"field": "@timestamp",
       
"interval": "month"
       
}
     
}
     
}
   
}
   
}
 
}
 
}
}

Pretty cool, huh?

꽤 멋지지 않은가?

Mixing Buckets and Metrics

On their own, metrics are a bit pedestrian. When looking at the examples last week, you may have been a bit underwhelmed. On their own, metrics can only calculate values against the global dataset.

그 자체로는, metric은 약간 평범하다. 지난 주의 예를 보면, 약간 실망했을 수도 있다. metric 자체적으로는 전체 data 집합에 대한 값만 계산할 수 있다.

But when metrics are embedded under a bucket as a sub-aggregation, they become infinitely more useful. Metrics will calculate their value based on the documents residing inside the bucket. This allows you to set up a range of criteria and sub-criteria with buckets, then place metrics to calculate values for your reports about each criteria.

그러나, metric이 sub-aggregation으로 bucket 아래에 포함되면, 훨씬 유용해진다. metric은 bucket 내부에 있는 document를 기반으로 값을 계산한다. 이렇게 하면, bucket으로 다양한 기준 및 하위 기준을 설정한 다음, 각 기준에 대한 보고서의 값을 계산하는 metric을 둘 수 있다.

As an example, let’s calculate the total number of cyclists injured in each borough:

예를 들어, 각 자치구에서 부상당한 자전거를 타다 부상당한 사람들의 총 수를 계산해 보자.

GET /nyc_visionzero/_search?search_type=count
{
 
"aggs" : {
 
"all_boroughs": {
   
"terms": {
   
"field": "borough"
   
},
   
"aggs": {
   
"total_cyclists_injured": {
     
"sum" : {
     
"field": "number_of_cyclist_injured"
     
}
   
}
   
}
 
}
 
}
}

We are using the same terms bucket to provide a criteria (“Which borough did this incident happen in?”), and then embedding a sum metric underneath it to calculate the total number of injuries. The response shows us that, although there were many incidents in each borough, relatively few of those involved cyclist injuries:

동일한 terms bucket을 사용하여 기준을 제공(어느 자치구에서 사고가 발생했는가?)하고, 아래에 sum metric을 포함하여 부상자의 총 수를 계산한다. response는 다음과 같은데, 각 자치구에서 많은 사고가 있었음에도, 자전거를 타다 부상당한 사람들은 상대적으로 적음을 보여준다.

{
 
"took": 19,
  "aggregations": {
   
"all_boroughs": {
     
"buckets": [
     
{
       
"key": "BROOKLYN",
       
"doc_count": 86549,
       
"total_cyclists_injured": {
         
"value": 2691
       
}
     
},
     
{
       
"key": "MANHATTAN",
       
"doc_count": 76122,
       
"total_cyclists_injured": {
         
"value": 2000
       
}
     
},
     
{
       
"key": "QUEENS",
       
"doc_count": 73000,
       
"total_cyclists_injured": {
         
"value": 1271
       
}
     
},
     
{
       
"key": "BRONX",
       
"doc_count": 36239,
       
"total_cyclists_injured": {
         
"value": 503
       
}
     
},
     
{
       
"key": "STATEN ISLAND",
       
"doc_count": 15763,
       
"total_cyclists_injured": {
         
"value": 69
       
}
     
}
     
]
   
}
 
}

}
Read Less

You’ll notice here that the metric is extracting the value of the `total_cyclists_injured` field and summing that for each borough, rather than just counting documents. Once you start mixing buckets and metrics, the sky’s the limit. Try running this example:

여기에서 metric이 단순히 document의 수를 세기 보다는, `total_cyclists_injured` field의 값을 추출하여 각 차치구마다 합을 구하는 것을 알 수 있다. bucket과 metric을 섞기 시작하면, 끝이 없다. 예제를 실행해 보자.

GET /nyc_visionzero/_search?search_type=count{
 
"aggs" : {
 
"all_boroughs": {
   
"terms": {
   
"field": "borough"
   
},
   
"aggs": {
   
"causes": {
     
"terms": {
     
"field": "contributing_factor_vehicle",
     
"size": 3
     
},
     
"aggs": {
     
"incidents_per_month": {
       
"date_histogram": {
       
"field": "@timestamp",
       
"interval": "month"
       
},
       
"aggs": {
       
"cyclist_injury_avg": {
         
"avg": {
         
"field": "number_of_cyclist_injured"
         
}
       
}
       
}
     
}
     
}
   
},
   
"total_cyclists_injured": {
     
"sum" : {
     
"field": "number_of_cyclist_injured"
     
}
   
}
   
}
 
},
 
"top_causes": {
   
"terms": {
   
"field": "contributing_factor_vehicle",
   
"size": 3
   
}
 
},
 
"outside_borough": {
   
"missing": {
   
"field": "borough"
   
},
   
"aggs": {
   
"total_cyclists_injured": {
     
"sum" : {
     
"field": "number_of_cyclist_injured"
     
}
   
}
   
}
 
}
 
}
}
Read Less

The aggregation is a bit large. But it is simple once you break it down into components:

aggregation은 꽤 거대하다. 그러나 일단 구성 요소로 나누면 간단하다.

  • all_boroughs.causes.incidents_per_month.cyclist_injury_avg: reports average number of cyclists injured per-month, per contributing cause factor, per borough
    월별, 사고 원인별, 자치구별 자전거를 타다 부상당한 사람들의 부상자들의 평균 수
  • all_boroughs.total_cyclists_injured: reports total cyclists injured per borough, irrespective of cause
    원인에 관계없이 자치구별 자전거를 타다 부상당한 사람들의 총수
  • top_causes: reports the top three contributing incident causes, irrespective of borough
    자치구에 관계없이 상위 3가지 사고 원인
  • outside_borough.total_cyclists_injured: reports total cyclists injured in areas outside of a borough
    자치구 외곽에서 자전거를 타다 부상당한 사람들의 총수

Conclusion

That last aggregation was pretty nifty, no? This entire report runs in a single API call and takes only milliseconds to execute. It operates on fresh, near-real-time data. As new incidents stream into your system, your aggregations will immediately update to reflect the new data. This is what makes Kibana so powerful: near-real-time rollups and summaries of your data, sliced and diced as you wish.

마지막 aggregation은 꽤 괜찮지 않은가? 이 전체  보고서는 단일 API 호출로 실행되고, 수 ms만에 실행된다. 거의 실시간에 가까운 data를 연산한다. 새로운 사고가 system에 들어오면 aggregation은 즉시 새로운 data를 반영하여 update한다. 이것이 Kibana를 매우 강력하게 만드는 요인이다. 거의 실시간에 가까운 data의 개요가 필요할 경우, 원하는 대로 가능하다.

These first two introductory articles have barely scratched the surface of aggregations in Elasticsearch. In the following articles, we will begin to dissect datasets and show how real insights can be extracted using aggregations. Stay tuned!

이들 처음 2개의 소개 게시물은 Elasticsearch aggregation의 겉핧기 정도이다. 다음에는 data 집합을 분석하고 aggregation을 통하여 실제로 통찰력을 추출할 수 있는 방법을 보여줄 것이다.

원문 : Intro to Aggregations pt. 2: Sub-Aggregations