본문 바로가기

Elasticsearch

[Elasticsearch] bucket sub-aggregation 하위 집계

반응형



Elasticsearch Aggregations, 집계

 

 

Elasticsearch 는 검색뿐 아니라 여러가지 연산을 할 수 있는 Aggregation 기능이 있다. Kibana에서 차트, 그래프 등으로 시각화시킬 때 사용하는 기능이 aggregation 이다. 

 

aggregations 에는 두 가지 종류가 있다. 

- Metrics aggregation : 숫자 또는 날짜 필드의 값으로 계산함

- Bucket aggregation : 범위나 keyword 값으로 그룹화함

 

그리고 확장하여 사용할 수 있는 aggregations 도 있다. 

- Sub-aggregation : bucket 하위 집계 

- Pipeline-aggregation : metrics aggregation 결과로 다시 집계 

 

이 포스팅에서는 Sub-aggregation 에 대한 개념 설명 및 실습 예제를 다룬다. 

** 아래 실습에서 사용된 도큐먼트 데이터 입력은 metrics aggregations 참조

 

 

sub-aggregations

bucket aggregation으로 만든 버킷 내부에 다시 aggregation 집계 (metrics or bucket 모두 가능)를 하는 방식이다. 

 

역 명으로 버킷(그룹)화 해서 그 내부에 passangers 필드의 평균 값 또한 나타내기 

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

결과 : 

  "aggregations" : {
    "stations" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "가락시장",
          "doc_count" : 5,
          "avg_psg_per_station" : {
            "value" : 1860.0
          }
        },
        {
          "key" : "잠실",
          "doc_count" : 5,
          "avg_psg_per_station" : {
            "value" : 2200.0
          }
        },
        {
          "key" : "잠실새내",
          "doc_count" : 3,
          "avg_psg_per_station" : {
            "value" : 2000.0
          }
        }
      ]
    }
  }

결과 aggregations > stations (사용자 임의 버킷명) > terms 버킷 & 그 안의 passangers 평균 값 이 같은 뎁스에 나와있다. 

 

 

line, 호선 별로 버킷을 만들고 그 안에 호선 별 역명 버킷화, 각 호선별 평균 승객 수 구하기 

GET stations/_search
{
  "size": 0,
  "aggs": {
    "lines": {
      "terms": {
        "field": "line.keyword"
      },
      "aggs": {
        "avg_psg_per_line": {
          "avg": {
            "field": "passangers"
          }
        },
        "stations_per_line": {
          "terms": {
            "field": "station.keyword"
          }
        }

      }
    }
  }
}

결과 : 

  "aggregations" : {
    "lines" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "3호선",
          "doc_count" : 5,
          "stations_per_line" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "가락시장",
                "doc_count" : 3
              },
              {
                "key" : "잠실",
                "doc_count" : 2
              }
            ]
          },
          "avg_psg_per_line" : {
            "value" : 1860.0
          }
        },
        {
          "key" : "1호선",
          "doc_count" : 4,
          "stations_per_line" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "잠실",
                "doc_count" : 3
              },
              {
                "key" : "잠실새내",
                "doc_count" : 1
              }
            ]
          },
          "avg_psg_per_line" : {
            "value" : 2250.0
          }
        },
        {
          "key" : "2호선",
          "doc_count" : 4,
          "stations_per_line" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "가락시장",
                "doc_count" : 2
              },
              {
                "key" : "잠실새내",
                "doc_count" : 2
              }
            ]
          },
          "avg_psg_per_line" : {
            "value" : 2000.0
          }
        }
      ]
    }
  }

 

버킷 안 버킷 끝없이 만들 순 있겠지만 뎁스가 증가할수록 elasticsearch의 작업량, 메모리 소모량이 기하급수적으로 늘어나 오류가 날 수도 있어서, 보통 2레벨 정도까지 사용하는 게 좋다고 한다. 

 

 

Reference : https://esbook.kimjmin.net/08-aggregations

반응형