본문 바로가기

Elasticsearch

[Elasticsearch] Metrics Aggregations 집계 정리

반응형

 

Elasticsearch Aggregations, 집계

 

 

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

 

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

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

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

 

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

- Sub-aggregation : bucket 하위 집계 

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

 

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

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

 

 

 

Metrics aggregation

 

Metrics aggregation으로 가장 많이 쓰이는 것은 min, max, sum, avg 등이 있다.

min : 최소값

max : 최대값

sum : 합

avg : 평균값 

 

 

aggregation을 실습해볼 12개의 도큐먼트 넣어주면서 index 생성

PUT stations/_bulk
{"index": {"_id": 1}}
{"date": "2022-12-25", "line": "1호선", "station": "잠실", "passangers": 1000}
{"index": {"_id": 2}}
{"date": "2022-12-26", "line": "2호선", "station": "잠실새내", "passangers": 1000}
{"index": {"_id": 3}}
{"date": "2022-12-27", "line": "3호선", "station": "잠실", "passangers": 1000}
{"index": {"_id": 4}}
{"date": "2022-12-31", "line": "2호선", "station": "가락시장", "passangers": 2000}
{"index": {"_id": 5}}
{"date": "2023-01-01", "line": "1호선", "station": "잠실새내", "passangers": 2000}
{"index": {"_id": 6}}
{"date": "2023-02-10", "line": "2호선", "station": "가락시장", "passangers": 2000}
{"index": {"_id": 7}}
{"date": "2023-04-23", "line": "3호선", "station": "가락시장", "passangers": 2000}
{"index": {"_id": 8}}
{"date": "2023-09-22", "line": "1호선", "station": "잠실", "passangers": 3000}
{"index": {"_id": 9}}
{"date": "2023-10-25", "line": "3호선", "station": "잠실", "passangers": 3000}
{"index": {"_id": 10}}
{"date": "2023-10-17", "line": "2호선", "station": "잠실새내", "passangers": 3000}
{"index": {"_id": 11}}
{"date": "2023-11-04", "line": "1호선", "station": "잠실", "passangers": 3000}
{"index": {"_id": 12}}
{"date": "2023-12-11", "line": "3호선", "station": "가락시장", "passangers": 3000}

 

 

 

min, max, sum, avg 실습

 

GET stations/_search
{
  "size": 0,
  "aggs": {
    "all_passangers": {
      "sum": {
        "field": "passangers"
      }
    }
  }
}

"size": 0 을 안 넣게되면 모든 데이터가 매칭되어 나오는데 집계만 필요할 경우 size : 0으로 넣어서 hits되는 데이터가 아무것도 안나오게 하면 더 빠르고 효율적이다. 

 

"aggs": { "내가 정하는 필드명" { "계산할 수식(min or max or sum or avg)" { "field": "계산할 필드명" } } } 

 

sum, min, max, avg 모두 적용해보기

GET stations/_search
{
  "size": 0,
  "aggs": {
    "all_passangers": {
      "sum": {
        "field": "passangers"
      }
    },
    "min_passangers": {
      "min": {
        "field": "passangers"
      }
    },
    "max_passangers": {
      "max": {
        "field": "passangers"
      }
    },
    "avg_passangers": {
      "avg": {
        "field": "passangers"
      }
    }
  }
}

결과 : 

{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 12,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "all_passangers" : {
      "value" : 26000.0
    },
    "avg_passangers" : {
      "value" : 2166.6666666666665
    },
    "max_passangers" : {
      "value" : 3000.0
    },
    "min_passangers" : {
      "value" : 1000.0
    }
  }
}

보통 검색 결과 데이터를 보여주는 "hits" (hits.hits X)  와 동일한 뎁스의 "aggregations" 라는 key가 생겼고 그 안에 집계 검색한 내용이 나온다. 

 

 

 

Stats 

min, max, sum, avg를 한 번에 보여주고 해당하는 도큐먼트들의 개수도 가져온다. 

 

GET stations/_search
{
  "size": 0,
  "aggs": {
    "station_passangers_stats": {
      "stats": {
        "field": "passangers"
      }
    }
  }
}

min, max..를 넣어주는 부분에 stats를 넣어주면 결과 : 

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 12,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "station_passangers_stats" : {
      "count" : 12,
      "min" : 1000.0,
      "max" : 3000.0,
      "avg" : 2166.6666666666665,
      "sum" : 26000.0
    }
  }
}

count : 아래 집계에 계산할 때 쓰인 도큐먼트 수를 보여준다. hits에 이 도큐먼트들이 안나오는 이유는 검색 query에 도큐먼트는 0개 보여줘 라고 요청했기 때문이다. 

 

 

 

 

Cardinality

필드의 값의 집합 (종류)를 알아볼 때 사용하는 cardinality

일반적으로 text 필드보다 숫자 필드, keyword, ip 등 에서 사용한다. 사용자 접속 로그에서 ip 주소 필드를 가지고 접속한 유저 파악 시에 주로 사용된다. 

 

위에서 입력한 station 데이터들 중 line 필드가 총 몇 종류가 있는지 계산해보기 

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

"field": "line" 만으로 검색하면 에러가 난다. 

 

결과 :

{
  "took" : 14,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 12,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "line_types" : {
      "value" : 3
    }
  }
}

총 3개의 line 호선이 있는 걸 알 수 있다. 

 

 

 

 

 

Percentiles, Percentile_ranks

값들을 백분위 별로 보는 방법 

- percentiles : % 구간 별 값을 보기 

- percentil_ranks : 값으로 그 값이 위치 해 있는 백분위 보기 

 

 

percentiles

GET stations/_search
{
  "size": 0,
  "aggs": {
    "passanger_percentiles": {
      "percentiles": {
        "field": "passangers"
      }
    }
  }
}

결과 : 

{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 12,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "passanger_percentiles" : {
      "values" : {
        "1.0" : 1000.0,
        "5.0" : 1000.0,
        "25.0" : 1500.0,
        "50.0" : 2000.0,
        "75.0" : 3000.0,
        "95.0" : 3000.0,
        "99.0" : 3000.0
      }
    }
  }
}

디폴트로 1,5,25,50,75,95,99% 구간에 위치 해 있는 값들을 표시해 준다. 구간을 커스텀하고 싶다면 아래와 같이 옵션을 주면 된다. 

GET stations/_search
{
  "size": 0,
  "aggs": {
    "passanger_percentiles": {
      "percentiles": {
        "field": "passangers",
        "percents": [0,1,50,99,100]
      }
    }
  }
}

결과 : 

  "aggregations" : {
    "passanger_percentiles" : {
      "values" : {
        "0.0" : 1000.0,
        "1.0" : 1000.0,
        "50.0" : 2000.0,
        "99.0" : 3000.0,
        "100.0" : 3000.0
      }
    }
  }

 

 

 

percentile_ranks

 

GET stations/_search
{
  "size": 0,
  "aggs": {
    "passanger_percentile_ranks": {
      "percentile_ranks": {
        "field": "passangers",
        "values": [1000,2000,3000]
      }
    }
  }
}

결과  : 

  "aggregations" : {
    "passanger_percentile_ranks" : {
      "values" : {
        "1000.0" : 16.666666666666664,
        "2000.0" : 50.0,
        "3000.0" : 100.0
      }
    }
  }

 

1000,2000,3000 값이 위치한 백분위가 나온다. 위의 방식은 성적이 상위 몇%인지 파악할 때 편리하게 사용이 가능하다. 

 

지금까지가 metrics aggregations이고 이제 다음에 볼 bucket은 "버킷화" = 그룹화 개념이다. 

Bucket aggregation 정리글 

 

[Elasticsearch] Bucket Aggregations 버킷 집계 정리

Elasticsearch Aggregations - Metric Aggregations - Bucket Aggregations Bucket Aggregations bucket aggregation은 주어진 조건으로 분류된 버킷 (집합)들을 만들고 각 버킷에 포함되는 도큐먼트들을 모아 그룹으로 구분하는

blckchainetc.tistory.com

 

 

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

반응형