Elasticsearch: Sub-Aggregations (하위 집계) 완벽 정리

Sub-Aggregations(하위 집계)는 버킷 집계(Bucket Aggregation) 안에서 또 다른 집계를 수행할 수 있도록 지원하는 기능입니다.
한 번의 쿼리로 그룹화된 데이터에 추가적인 분석을 수행 가능
Bucket Aggregation 안에 다시 Bucket 또는 Metrics Aggregation을 중첩하여 사용 가능
여러 계층의 집계를 수행할 수 있어 복잡한 데이터 분석에 적합

이번 글에서는 Sub-Aggregations의 개념, 주요 기능, 실전 예제까지 상세히 알아보겠습니다.


1. Sub-Aggregations 개요

     
개념 Bucket Aggregation 내에서 추가 집계 수행  
사용 목적 그룹화된 데이터 내에서 추가적인 통계 분석 수행  
주요 유형 버킷 안에 Metrics Aggregation 적용 버킷 안에 또 다른 버킷 생성  

2. 데이터 예제 (지하철 승객 수 데이터)

Sub-Aggregations을 테스트할 데이터를 준비합니다.

📌 예제 1: my_stations 인덱스 생성 및 데이터 입력

PUT my_stations/_bulk
{"index": {"_id": "1"}}
{"date": "2019-06-01", "line": "1호선", "station": "종각", "passangers": 2314}
{"index": {"_id": "2"}}
{"date": "2019-06-01", "line": "2호선", "station": "강남", "passangers": 5412}
{"index": {"_id": "3"}}
{"date": "2019-07-10", "line": "2호선", "station": "강남", "passangers": 6221}
{"index": {"_id": "4"}}
{"date": "2019-07-15", "line": "2호선", "station": "강남", "passangers": 6478}
{"index": {"_id": "5"}}
{"date": "2019-08-07", "line": "2호선", "station": "강남", "passangers": 5821}
{"index": {"_id": "6"}}
{"date": "2019-08-18", "line": "2호선", "station": "강남", "passangers": 5724}
{"index": {"_id": "7"}}
{"date": "2019-09-02", "line": "2호선", "station": "신촌", "passangers": 3912}
{"index": {"_id": "8"}}
{"date": "2019-09-11", "line": "3호선", "station": "양재", "passangers": 4121}
{"index": {"_id": "9"}}
{"date": "2019-09-20", "line": "3호선", "station": "홍제", "passangers": 1021}
{"index": {"_id": "10"}}
{"date": "2019-10-01", "line": "3호선", "station": "불광", "passangers": 971}

지하철 승객 수 데이터를 포함한 샘플 데이터 생성


3. Bucket 내부에서 Metrics Aggregation 수행

버킷 그룹별로 추가적인 통계(평균, 최대, 최소 등)를 계산 가능
terms(역 이름) 기준으로 그룹화 후, 각 역의 평균 승객 수 계산

📌 예제 2: station.keyword 기준으로 그룹화 후 평균 승객 수 계산

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

각 역별 평균 승객 수(avg_psg_per_st) 계산 가능


4. Bucket 내부에서 또 다른 Bucket Aggregation 수행

하나의 Bucket 내에서 또 다른 기준으로 데이터를 그룹화 가능
지하철 노선(line.keyword) → 해당 노선의 역(station.keyword) 순으로 그룹화

📌 예제 3: 노선별(line.keyword)로 그룹화 후, 각 노선의 역(station.keyword) 그룹화

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

노선별 → 해당 노선의 역을 그룹화하는 예제


5. Bucket 내부에서 Bucket + Metrics Aggregation 수행

버킷 안에 또 다른 버킷을 만들고, 그 내부에서 통계 연산 수행 가능
지하철 노선(line.keyword) → 역(station.keyword) → 평균 승객 수(avg_passangers) 순으로 계산

📌 예제 4: 노선별 → 역별 → 평균 승객 수 계산

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

노선별 그룹화 후, 각 역별 평균 승객 수까지 계산하는 예제


6. Sub-Aggregations 주의사항

     
하위 버킷이 많아지면 성능 저하 발생 너무 깊은 버킷 구조는 피할 것  
최대 2~3단계의 Sub-Aggregations을 권장 Elasticsearch 메모리 사용량 증가 가능  
데이터 양이 많다면 size 제한을 걸어야 함 기본 size 값은 10개  

7. 정리

     
버킷 내부에서 통계 연산 terms + avg 그룹화된 데이터 내에서 평균/최대/최소 등 계산
버킷 내부에서 또 다른 그룹화 terms + terms 하나의 그룹화된 데이터 내에서 추가 그룹화
버킷 + 하위 버킷 + 통계 연산 terms + terms + avg 2단계 이상의 그룹화 후 통계 연산 수행

8. 마무리

Sub-Aggregations을 활용하면 데이터를 더욱 정교하게 분석 가능
Bucket 내부에서 또 다른 Bucket 및 Metrics Aggregation 수행 가능
단, 너무 깊은 계층의 Sub-Aggregations은 성능 저하를 유발할 수 있음

다음 학습에서는 고급 Aggregations 기법 및 성능 최적화 방법을 다루겠습니다! 🚀

+ Recent posts