[ElasticSearch] 집계 (Aggregations)

donghyeok·2023년 2월 23일

ElasticSearch

목록 보기
8/8

집계 (Aggregation)

ES는 검색엔진으로 개발되었지만 지금은 로그분석을 비롯한 다목적 데이터 시스템으로 사용되고 있다.
이렇게 다양한 용도로 활용될 수 있는 이유는 데이터 검색 뿐 아니라 여러가지 연산을 할 수 있는 집계 기능 덕분이다.

Aggregation의 사용방법은 다음과 같다. _search API에서 쿼리문과 같은 수준의 지정자 aggs를 명시하고 그 아래 임의의 aggregation 이름을 입력한 뒤 사용할 aggregation 종류와 옵션을 명시한다.
한번의 쿼리로 여러 aggs를 입력할 수도 있다.

GET <인덱스명>/_search
{
  "query": {
    … <쿼리 구문> …
  },
  "aggs": {
    "<임의의 aggregation 1>": {
      "<aggregation 종류>": {
        … <aggreagation 구문> …
      }
    },
    "<임의의 aggregation 2>": {
      "<aggregation 종류>": {
        … <aggreagation 구문> …
      }
    }
  }
}

Aggregation에는 크게 MetricsBucket 두 종류가 있으며 차이는 다음과 같다.

  • Metric : 숫자 또는 날짜 필드를 가지고 계산을 하는 aggs
  • Bucket : 범위나 keyword 값 등을 가지고 도큐먼트들을 그룹화 하는 aggs

1. 메트릭 (Metrics Aggregation)

min, max, sum, avg, stats

가장 흔하게 사용되는 metrics agg는 min, max, sum, avg이다.
stats은 min, max, sum, avg값을 모두 가져오는 metrics agg이다.
다음은 sum agg의 예제이다.

//passangers 필드의 합을 가져오는 agg
GET my_stations/_search
{
  "size": 0,               //hits에 불필요한 도큐먼트 내용이 안나옴, 도큐먼트 fetch 생략 
  "aggs": {
    "all_passangers": {
      "sum": {
        "field": "passangers"
      }
    }
  }
}

아래와 같이 쿼리문을 같이 입력해서 조건을 줄 수도 있다.

GET my_stations/_search
{
  "query": {
    "match": {
      "station": "강남"
    }
  },
  "size": 0,
  "aggs": {
    "gangnam_passangers": {
      "sum": {
        "field": "passangers"
      }
    }
  }
}

cardinality

필드의 값이 모두 몇종류인지 분포값을 알기위해 사용한다. 일반적으로 text 필드에는 사용할 수 없고
숫자, keyword, ip 필드 등에 사용이 가능하다.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "uniq_lines ": {
      "cardinality": {
        "field": "line.keyword"
      }
    }
  }
}

percentiles, percentile_ranks

값들을 백분위 별로 보기 위해서 percentiles agg 사용이 가능하다
percentiles agg는 디폴트로 1%, 5%, 25%, 50%, 75%, 95%, 99% 구간에 위치해 있는 값들을 표시한다.
백분위 구간을 직접 지정하려면 percents 옵션을 배열 형태로 지정해서 사용이 가능하다.
percentiles_ranks agg는 반대로 값을 입력해서 그 값이 위치해 있는 백분위를 볼 수 있다.

2. 버킷 (Bucket Aggregation)

Bucket agg는 주어진 조건으로 분류된 버킷들을 만들고, 각 버킷에 소속되는 도큐먼트들을 모아 그룹으로 구분하는 것이다.
각 버킷 별로 포함되는 개수는 doc_count값에 기본표시되며 각 버킷 안에 metrics agg를 이용해 다른 계산이 가능하다.
주로 사용되는 Bucket agg는 Range, Histogram, Terms 등이 있다.

Range

range는 숫자 필드 값으로 범위를 지정하고 각 범위에 해당하는 버킷을 만드는 agg이다.
field옵션에 해당 필드 이름을, ranges 옵션에 배열로 from, to를 가진 오브젝트 값을 나열하여 범위를 지정한다.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "passangers_range": {
      "range": {
        "field": "passangers",
        "ranges": [
          {
            "to": 1000
          },
          {
            "from": 1000,
            "to": 4000
          }
        ]
      }
    }
  }
}

Histogram

histogram도 range와 마찬가지로 숫자 필드의 범위를 나누는 agg이다.
histogram은 from, to 객체 배열 대신 interval 옵션으로 주어진 간격 크기대로 버킷을 구분한다.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "passangers_his": {
      "histogram": {
        "field": "passangers",
        "interval": 2000
      }
    }
  }
}

date_range, date_histogram

range, histogram agg는 숫자 필드를 대상으로 하는데 동일한 기능을 날짜 필드에도 적용이 가능하다.
위 agg는 시계열 데이터에서 날짜별로 값을 표시할 때 매우 유용하다.
방법은 동일하며 date_histogram 사용시 ìnterval 필드에 day, month, week 등이 사용 가능하다.

terms

앞에서 살펴본 agg들은 모두 숫자, 날짜를 가지고 구간을 나누는 aggs였다.
terms agg는 keyword 필드의 문자열 별로 버킷을 나누어 집계한다.
terms agg는 field 외에도 가져올 버킷의 개수를 지정하는 size 옵션이 있으며 디폴트는 10이다.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "stations": {
      "terms": {
        "field": "station.keyword", 
        "size" : 20
      }
    }
  }
}

3. 하위 집계 (Sub-Aggregations)

Bucket Agg로 만든 버킷들 내부에 다시 "aggs" : {}을 선언해서 또다른 버킷을 만들거나 Metrics Agg를 만들어 사용이 가능하다.
다음은 terms agg를 이용해서 역 버킷 별로 avg agg를 이용해서 탑승객 필드의 평균을 계산하는 예제이다.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "stations": {
      "terms": {
        "field": "station.keyword"
      },
      "aggs": {
        "avg_psg_per_st": {
          "avg": {
            "field": "passangers"
          }
        }
      }
    }
  }
}

다음처럼 버킷을 만들고 그 안에 또다시 버킷을 만들 수도 있다.
다음은 line.keyword 필드 버킷을 만들고 그 안에 또다시 station.keyword 필드 버킷을 만드는 예제이다.
주의할 점은 하위 버킷이 깊어질수록 ES의 작업량과 메모리 소모량이 기하급수적으로 늘어나므로 2레벨을 넘기는 버킷은 생성하지 않는 것이 좋다.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "lines": {
      "terms": {
        "field": "line.keyword"
      },
      "aggs": {
        "stations_per_lines": {
          "terms": {
            "field": "station.keyword"
          }
        }
      }
    }
  }
}

4. 파이프라인 (Pipeline Aggregation)

aggs 중에는 metrics agg의 결과를 새로운 입력으로 하는 pipeline agg가 있다.
pipeline에는 다른 버킷의 결과를 다시 연산하는 min_bucket, max_bucket, avg_buckey, sum_bucket, stats_bucket,
이동 평균을 구하는 moving_avg, 미분값을 구하는 derivative, 값의 누적합을 구하는 cumulative_sum 등이 있다.
파이프라인에서는 buckets_path": "<버킷 이름>옵션을 이용해 입력값으로 사용할 버킷을 지정한다.

다음은 date_histogram을 사용해서 월별로 나눈 passangers 합계 sum에 대해 누적합을 구하는 예제이다.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "months": {
      "date_histogram": {
        "field": "date",
        "interval": "month"
      },
      "aggs": {
        "sum_psg": {
          "sum": {
            "field": "passangers"
          }
        },
        "accum_sum_psg": {
          "cumulative_sum": {
            "buckets_path": "sum_psg"
          }
        }
      }
    }
  }
}

출처 : https://esbook.kimjmin.net/

0개의 댓글