Archive

[Elasticsearch] 엘라스틱서치 집계 ( Metric Aggregation / Bucket Aggregation / Pipeline Aggregation ) 본문

------- DE -------/ELK

[Elasticsearch] 엘라스틱서치 집계 ( Metric Aggregation / Bucket Aggregation / Pipeline Aggregation )

enent 2022. 6. 3. 22:51
반응형
0. Overview
1. Metirc Aggregation
2. Bucket Aggregation
3. Combination of Aggregations
    3.1 Bucket & Metric Aggregations
    3.2 Sub Bucket Aggregations
    3.3 Pipeline Aggregations

 

0. Overview

  • Kibana가 집계 기능을 기반으로 동작하기 때문에 집계를 제대로 이해하는 것이 중요하다
  • 메트릭 집계 / 버킷 집계로 나뉜다
  • Search API 요청에 aggs파라메타 이용하여 집계를 생성한다

 

1. Metirc Aggregation

  • avg, min, max, sum, percentiles, stats, cardinality, geo-centroid 등 주로 통곗값 계산이 목적
    - stats : min / max / sum / avg / count 를 한번에 제공
    - cardinarity : unique 한 값 개수
    - geo-centroid : field 내부의 위치 정보의 centroid를 계산

 

ex1) avg 평균 집계

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

- size : 0으로 설정 시, 집계에 사용한 Document를 결과에 포함시키지 않음

- stats_aggs : 집계 이름. 원하는 형태로 지정 가능
- field : avg를 구하고 싶은 필드명 

 

 

ex2) percentile 백분위 집계

GET kibana_sample/_search
{
  "size" : 0,
  "aggs" : {
    "stats_aggs" : {
      "percentiles" : { 
        "field" : "products.base_price",
        "percents" : [
          25,
          50
        ]
      }
    }
  }
}

- percents : 해당 백분위 사이에 속하는 데이터를 찾아줌

 

 

ex3) cardinality unique count집계

GET kibana_sample/_search
{
  "size" : 0,
  "aggs" : {
    "cardi_aggs" : {
      "cardinality" : { 
        "field" : "products.base_price",
        "precision_threshold" : 100
      }
    }
  }
}
  • precision_threshold 
    - 값이 크면 정확도 증가 but 리소스 많이 소모 / 값이 작으면 정확도 감소 but 리소스 덜 소모|
    - 중복을 제거한 항목수가 적을수록 정확도가 올라감
    - 대상의 크기에 상관없이 일정이상의 메모리를 사용하지 않음
    - Default 값은 3000, 최대 40000까지 값 설정 가능

 

ex4) 검색 결과 내 집계

집계 전 Query를 통해 필요한 Document만 검색 후 이를 바탕으로 집계

GET kibana_sample/_search
{
  "size" : 0,
  "query" : {
    "term" : { 
      "day_of_week" : "Monday"
    }
  },
  "aggs" : {
    "query_aggs" : {
      "sum" : { 
        "field" : "products.base_price"
      }
    }
  }
}

 

 

2. Bucket Aggregation

  • histogram, range, terms, filters 등 주로 특정 기준에 맞춰서 Document를 Grouping하는 용도로 사용 (RDB GroupBy 역할)
    - histogram : 숫자 타입 필드를 일정 간격으로 분류
    - date_histogram : 날짜/시간 타입 필드를 일정 날짜/시간 간격으로 분류
    - range : 숫자 타입 필드를 사용자가 지정하는 범위 간격으로 분류
    - date_range : 날짜/시간 타입 필드를 사용자가 지정하는 날짜/시간 간격으로 분류
    - terms : 필드에 많이 나타나는 term들을 기준으로 분류
    - significant_terms : Index내 전체 문서 대비 현재 검색 조건에서 통계적으로 유의미한 값들을 기준으로 분류
    - filters : 각 그룹에 포함시킬 document의 조건 직접 지걱 ( 검색에 사용되는 query와 동일하게 지정)

 

ex1) histogram 집계

GET kibana_sample/_search
{
  "size" : 0,
  "aggs" : {
    "histogram_aggs" : {
      "histogram" : { 
        "field" : "products.base_price",
        "interval" : 100
      }
    }
  }
}

- Interval : 집계 간격

 

 

ex2) range 집계

각 버킷의 범위 직접 지정 가능

GET kibana_sample/_search
{
  "size" : 0,
  "aggs" : {
    "range_aggs" : {
      "range" : { 
        "field" : "products.base_price",
        "ranges" : [
        { "from" : 0, "to": 50 },
        { "from" : 50, "to": 100 },
        { "from" : 100, "to": 200 },
        { "from" : 200, "to": 1000 }
        ]
      }
    }
  }
}

 

ex3) term 집계

Field의 Unique한 값을 기준으로 버킷을 나눌 때 사용

GET kibana_sample/_search
{
  "size" : 0,
  "aggs" : {
    "term_aggs" : {
      "terms" : { 
        "field" : "day_of_week",
        "size" : 6,
        "show_term_doc_count_error" : true,
        "shard_size" : 100
      }
    }
  }
}

 

- size : default = 10, 지정한 field내 document가 많은 상위 N개를 지정
- show_term_doc_count_error : doc_count_error_upper_bound 값을 bucket마다 확인할 수 있음
  ▷ 0 이면 오류가 없음을 의미. 이상 값이 나오면 shard_size를 조정해야함
- shard_size : term집계 과정에서 개별 shard에서 집계를 위해 처리하는 개수 

  ▷ shard 크기가 크면 정확도도 오르지만 리소스 사용량도 같이 올라감

  ▷ default 값 = size (bucket개수) * 1.5 + 10

 

Result 로 아래와 같은 형태의 값이 리턴된다

"aggregations" : {
  "term_aggs" : {
    "doc_count_error_upper_bound" : 0,
    "sum_other_doc_count": : 579, 
    "buckets" : [
    {
        "key" : "Thursday",
        "doc_count" : 775
    },
    
    ...
    
    ]
  }
}

- doc_count_error_upper_bound : bucket이 잠재적으로 count하지 못할 document 수 
  ▷ shard에 document를 저장하고 분산하는 과정에서 오류가 발생할 수 있음 ( ex) size 설정값으로 인해 버려지는 값이 각 샤드에서 다르면, 최종 기대값이랑 다른 결과값이 나올 수 있음 )

- sum_other_doc_count : bucket에는 있으나 size때문에 보이지 않는 document 수

 

 

3. Combination of Aggregations

3.1 Bucket & Metric Aggregations

  • RDB에서 GROUP BY 후 통계 함수 사용하는 것과 동일하다
  • 들여쓰기 계층에 따라 집계 위치가 다르므로 주의해야 한다

 

ex) term 집계 후 min/sum

▼ Bucket집계 내부에서 2개의 Metric집계가 동작 = Bucket별 sum/min

GET kibana_sample/_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"
          }
        }
      }
    }
  }
}

 

 

3.2 Sub Bucket Aggregations

  • Bucket안에서 Bucket집계를 요청하는 구조 (Tree 형태)
    - 보통 2단계 초과 하지 않는 것을 추천 (클러스터 과부하 가능성)
  • 들여쓰기 계층에 따라 집계 위치가 다르므로 주의해야 한다

 

ex) histogram 집계 후 term 집계

histogram으로 나누어진 bucket 내부에서 다시 bucket을 나누어 값이 제일 큰 2개 추출

GET kibana_sample/_search
{
  "size" : 0,
  "aggs" : {
    "histogram_aggs" :{
      "histogram" : {
        "field" : "products.base_price",
        "interval" : 100
      },
      "aggs" : {
        "term_aggs" : {
          "terms" : { 
            "field" : "day_of_week",
            "size" : 2
          }
        }
      }
    }
  }
}

 

 

3.3 Pipeline Aggregations

  • 이전 집계 결과를 Input으로 삼아 다시 집계하는 방식
  • Search API 사용시 buckets_path를 반드시 입력해야함

 

1) Parent Aggregation

  • 기존 집계 내부에서 기존 집계를 이용한 집계 작업을 한다. 결과값도 기존 집계 내부에서 나타난다
  • 부모 집계는 단독으로 사용할 수 없다
    ▷ 반드시 다른 집계가 있어야하고, 그 집계 결과를 부모 집계가 사용하는 형태이다
  • aggregation 종류
    - derivative : 기존 집계의 미분
    - cumulative_sum : 기존 집계의 누적합

ex) cumulative sum을 구하는 parent aggregation

부모 집계는 sum_aggs를 Input으로 받아 최종적으로 각 bucket의 누적합 계산

 

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

 

Result 로 아래와 같은 형태의 값이 리턴된다.

"aggregations" : {
  "histogram_aggs" : {
    "buckets" : [
    {
        "key" : 0.0,
        "doc_count" : 775,
        "sum_aggs" : {
          "value" : 348124.128
        },
        "cum_sum" : { 
          "value" : 348124.128
        }
    },
    {
        "key" : 100.0
        "doc_count" : 263,
        "sum_aggs" : {
          "value" : 22002.0
        },
        "cum_sum" : { 
          "value" : 370126.128
        }
    },
    
    ...
    
    ]
  }
}

 

 

2) Sibiling Aggregation

  • 기존 집계 외부에서 기존 집계를 이용한 집계 작업을 한다. 
  • 일반적으로 한 개의 최종 통계 결과값을 낼 때 사용한다.
  • aggregation 종류
    - min_bucket / max_bucket / avg_bucket / sum_bucket : 기존 집계 중 최소/최대/평균/총합을 구함
    - stat_bucket  : 기존 집계의 min,max,sum,count,avg를 한번에 요약해서 보여줌
    - percentile_bucket : 기존 집계의 백분위값을 구함
    - moving_avg : 기존 집계의 이동평균값을 구함 (순차 데이터에서 가능)

 

ex) 최종 합을 구하는 sibiling aggregation

부모 집계는 sum_aggs를 Input으로 받아 최종적으로 각 bucket의 누적합 계산

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

- ">" in buckets_path : 하위 집계 경로를 나타냄

 

 

Result 로 아래와 같은 형태의 값이 리턴된다.

"aggregations" : {
  "term_aggs" : {
    "doc_count_error_upper_bound" : 0,
    "sum_other_doc_count": : 3130, 
    "buckets" : [
      {
        "key" : "Thursday",
        "doc_count" : 775,
        "sum_aggs" : {
          "value" : 58020.324
        }
      },
      {
        "key" : "Tuesday",
        "doc_count" : 770,
        "sum_aggs" : {
          "value" : 58341.976
        }
      }
    ]
  },
  "sum_total_price" : {
    "value" : 115362.30
  }
}

 

 

 

 

*Pipeline Aggregation vs Sub Bucket Aggregation ( 파이프라인 집계 vs 서브버킷 집계) 

Sub-aggregations : 개별 버킷에서 작동, 버킷 내 context에서 수행
Pipeline aggregations : 일반 집계 "이후"에 작동, 버킷 전체에 걸쳐서 계산됨

 

 

 

Reference
Elastic Stack 개발부터 운영까지 - 5. ElasticSearch - Aggregation
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
https://stackoverflow.com/questions/36736921/elasticsearch-difference-between-sub-aggregations-and-pipeline-aggregations

 

반응형
Comments