🛠️TOOL/🔭Elasticsearch

[Elasticsearch] - 집계(aggregation)

KangManJoo 2024. 4. 1. 15:37

집계(aggregation)란?

엘라스틱에서 집계는 데이터를 그룹핑하고 통곗값을 얻는 기능으로 강력한 검색 성능과 ES를 고성능 집계 엔진으로 활용하게 해준다. 집계를 잘 이해할수록 키바나를 더 잘 사용할 수 있다.

 

ES에는 다음과 같은 집계들이 있다.

  • 메트릭 집계
  • 버킷 집계
  • 파이프라인 집계

 

집계의 요청과 응답 형태

집계를 위해서 특별한 API를 사용하지 않아도, Search API의 요청 본문에 aggs 파라미터를 추가함으로서 쿼리에 대한 집계를 생성할 수 있다.

메트릭 집계

메트릭 집계는 필드의 최소/최대/합계/평균 등 통계 결과를 보여준다.

다음은 메트릭 집계의 종류이다.

메트릭 집계 설명
avg 필드의 평균값을 계산한다.
min 필드의 최솟값을 계산한다.
max 필드의 최댓값을 계산한다.
sum 필드의 총합을 계산한다.
percentiles 필드의 백분윗값을 계산한다.
stats 필드의 min, max, sum, avg, count를 한 번에 볼 수 있다.
cardinality 필드의 유니크한 값 개수를 보여준다.
geo-centroid 필드 내부의 위치 정보의 중심점을 계산한다.

 

평균값 예시

샘플 데이터를 통해 간단한 집계 요청을 작성해보자.

GET kibana_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "stats_aggs": {
      "avg": {
        "field": "products.base_price"
      }
    },
    "max_agg": {
      "max": {
        "field": "products.base_price"
      }
    }
  }
}

stats_aggs와 max_agg는 각각 사용자가 작성한 집계의 이름이고, 원하는 메트릭 집계와 집계를 위한 필드를 설정한다.

 

결과는 다음과 같이 볼 수 있다.

mZbG9z6.png|598

 

백분위 예시

다음과 같이 percentiles를 이용해 백분위 집계도 정의할 수 있다.

YV4aj83.png|599

 

카디널리티 예시

카디널리티 집계는 SQL의 distinct count와 같다.

다만 ES에서는 카디널리티의 파라미터로 precision_threshold를 제공한다.

이는 정확도 수치로, 값이 작으면 정확도가 떨어지는 대신 시스템 리소스를 덜 소모한다.

일반적으로 카디널리티 결과값보다 큰 값을 넣어야 정확한 값을 얻을 수 있으므로, 결과가 변하지 않을때까지 조금씩 precision_threshold를 증가시켜주자.

 

버킷 집계

메트릭 집계의 목적이 통곗값 계산이라면, 버킷 집계는 특정 기준에 맞춰서 도큐먼트를 그룹핑하는 역할을 한다. 버킷은 도큐먼트가 분할되는 단위로 나뉜 각 그룹을 의미한다.

 

버킷 집계의 종류는 다음과 같다.

버킷 집계 설명
histogram 숫자 타입 필드를 일정 간격으로 분류한다.
date_histogram 닐찌/시간 타입 필드를 일정 날짜/시간 간격으로 분류한다.
range 숫자 타입 필드를 사용자가 지정하는 범위 간격으로 분류한다.
date_range 날짜/시간 타입 필드를 사용자가 지정하는 날짜/시간 간격으로 분류한다.
terms 필드에 많이 나타나는 용어들을 기준으로 분류한다.
significant_terms terms와 동일하나 모든 값 대상이 아닌 인덱스 내 통계적으로 유의미한 값들을 기준으로 분류한다.
filters 각 그룹에 포함시킬 문서의 조건을 직접 명시한다.

 

히스토그램 집계 사용예시

interval은 히스토그램의 간격이며 다음과 같이 100개를 기준으로 값을 건너뛰며 분류할 수 있다.

조금 더 원하는 대로 각각 다른 간격을 주고싶다면 range로 범위 집계를 이용할 수 있다.

 

용어 집계 사용 예시

용어 집계는 필드의 유니크한 값을 기준으로 버킷을 나눌 때 사용한다.

 

GET kibana_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs":{
    "term_aggs":{
      "terms":{
        "field": "day_of_week",
        "size":6
      }
    }
  }
}

위 예시는 day_of_week 의 값을 기준으로 도큐먼트 수가 많은 상위 6개의 버킷을 요청한다.

size가 6이므로 도큐먼트 수가 가장 적은 요일이 보이지 않게 된다.

 

다만 용어 집계는 분산 시스템 환경에서 오류가 발생할 수 있다.

각 노드에서 뽑은 상위 노드들의 목록이 다르다면, 취합하는 과정에서 오류가 생길 수 있기 때문이다.

개별 샤드에서 집계를 위해 처리하는 개수를 shard_size 파라미터로 크게 설정해주면, 정확도를 올릴 수 있다.

 

집계의 조합

메트릭 집계로 특정 필드의 통계를 구할 수 있고, 버컷 집계로 도큐먼트를 그룹핑할 수 있다.

그리고 두 집계를 조합하면 다양한 그룹별 통계를 계산할 수 있다.

 

가장 주문량이 많은 다섯 요일의 각각의 총 매출과 평균 매출을 보는 집계 요청은 다음과 같다.

GET kibana_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs":{
    "term_aggs":{
      "terms":{
        "field": "day_of_week",
        "size":5
      },
      "aggs":{
        "avg_aggs":{
          "avg":{
            "field": "products.base_price"
          }
        },
        "sum_aggs":{
          "sum":{
            "field": "products.base_price"
          }
        }
      }
    }
  }
}

 

서브 버킷 집계

서브 버킷은 버킷 안에서 다시 버킷 집계를 요청하는 집계다.

위에서 요일을 나누고 나눈 요일(버킷) 내에서 평균을 낸 것도 서브 버킷 집계라고 볼 수 있다.

 

파이프라인 집계

파이프라인 집계는 이전 집계의 결과를 다음 단계에서 다시 입력으로 삼아 집계하는 방식이다.

이 과정에는 부모 집계와 형제 집계 두 가지 유형이 있다.

 

형제 집계는 기존 집계를 참고해 집계를 수행한다. 결과는 기존 집계와 동일선상에서 나온다.

부모 집계는 기존 집계 결과를 이용해 새로운 집계를 생성하고, 결과는 기존 집계 내부에서 나온다.

 

형제 집계의 종류는 다음과 같다.

  • min_bucket = 기존 집계 중 최솟값을 구한다.
  • max_bucket = 기존 집계 중 최댓값을 구한다.
  • avg_bucket = 기존 집계의 평균값을 구한다.
  • sum_bucket = 기존 집계의 총합을 구한다.
  • stat_bucket = 기존 집계의 min, max, sum, count, avg를 구한다.
  • percentile_bucket = 기존 집계의 백분윗값을 구한다.
  • moving_avg = 기존 집계의 이동 평균을 구한다.

 

부모 집계의 종류는 다음과 같다.

  • derivative = 기존 집계의 미분을 구한다.
  • cumulative_sum = 기존 집계의 누적합을 구한다.

 

형제 집계 예시

GET kibana_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs": {
    "term_aggs": {
      "terms": {
        "field": "day_of_week",
        "size": 2
      },
      "aggs": {
        "sum_aggs": {
          "sum": {
            "field": "products.base_price"
          }
        }
      }
    },
    "sum_total_price": {
      "sum_bucket": {
        "buckets_path": "term_aggs>sum_aggs"
      }
    }
  }
}

위 집계는 요일을 기준으로 상위 2개 버킷을 생성하고 각 요일의 총 매출을 나타낸뒤, 다시 sum_bucket 형제 집계를 이용해 두 요일의 총 매출을 더한 값을 나타낸다.

파이프라인 집계는 버킷 경로를 넣어주어야하는데 > 를 통해 하위 집계 경로를 나타낸다.

 

부모 집계 예시

GET kibana_sample_data_ecommerce/_search
{
  "size": 0,
  "aggs":{
    "histogram_aggs":{
      "histogram": {
        "field": "products.base_price",
        "interval": 50
      },
      "aggs":{
        "sum_aggs":{
          "sum":{
            "field": "taxful_total_price"
          }
        },
        "cum_sum":{
          "cumulative_sum": {
            "buckets_path": "sum_aggs"
          }
        }
      }
    }
  }
}

부모 집계는 기존 집계 내부에서 집계 작업을 한다.

위 집계는 누적합을 구한다.

 


집계는 키바나 시각화에서 반드시 필요하므로, 메트릭 집계와 버킷 집계, 파이프라인 집계의 차이를 이해하고 사용법을 익혀두자.