[ElasticSearch] aggregation 함수 (feat. groupBy, orderBy, LIMIT)

조갱·2022년 11월 6일
0

ElasticSearch

목록 보기
5/7
post-thumbnail

ElasticSearch 에서 데이터를 그룹핑 해서 작업할 수 있는 Aggregation (이하 aggs) 기능을 제공한다.

크게 분류하자면,

  • 메트릭 (Metric) > 수치 계산 (Sum, Min, Max ...)
  • 버킷 (Bucket) > 주어진 조건으로 그룹을 만듦 (histogram, term...)
  • 하위 (Sub) > aggs된 데이터에 다시 aggs 를 수행
  • 파이프라인 (Pipeline) > metric Aggs의 결과를 새로운 입력으로 받아 다시 aggs 수행

ElasticSearch 를 사용해본지 얼마 안된 개발자들은 용어가 생소할 수 있으니, MySQL과 비교하여 다뤄보도록 한다.


이곳에 있는 데이터 모델을 기반으로 합니다.

PUT person/_doc/1
{
  "name":"김남자",
  "gender":"M",
  "age": 27,
  "address": {
    "personId": 1,
    "country": "KR",
    "city": "Suwon"
  }
}

PUT person/_doc/2
{
  "name":"김이상",
  "gender":"M",
  "age": 2,
  "address": {
    "personId": 2,
    "country": "KR",
    "city": "Seoul"
  }
}

PUT person/_doc/3
{
  "name":"최여자",
  "gender":"F",
  "age": 25,
  "address": {
    "personId": 3,
    "country": "KR",
    "city": "Seoul"
  }
}

Metric Aggregation

MySQL 의 SUM, MAX, MIN 등 집계 함수와 유사하다.

공무원 '김공무' 는 부동산을 가지고 있는 가장 어린 사람을 검색하고자 한다.

MySQL

SELECT MIN(age)
FROM Person
GET /person/_search
{
  "size": 0, 
  "aggs": {
    "byAge": {
      "min": {
        "field": "age"
      }
    }
  }
}


부동산을 가지고 있는 사람 중 가장 어린 사람은 2살이다.

Bucket Aggregation

Mysql 의 GroupBy 와 유사하다.

공무원 '김공무'는, 각 성별별로 부동산을 가지고 있는 사람이 몇명인지 궁금하다.

SELECT gender, COUNT(1)
FROM Person
GROUP BY gender
GET /person/_search
{
  "size": 0, 
  "aggs": {
    "byGender": {
      "terms": {
        "field": "gender"
      }
    }
  }
}

남자가 2개의 부동산을,
여자가 1개의 부동산을 가지고 있음을 알 수 있다.

Sub Aggregation

MySQL 에서 여러 집계함수를 중첩해서 사용하는 것과 유사하다.

공무원 '김공무'는 성별, 나이별로 갖고 있는 부동산의 수가 궁금하다.

SELECT gender, age
FROM Person
GROUP BY gender, age
GET /person/_search
{
  "size": 0, 
  "aggs": {
    "byGender": {
      "terms": {
        "field": "gender"
      },
      "aggs": {
        "byAge": {
          "terms": {
            "field": "age"
          }
        }
      }
    }
  }
}

  • 남자
    • 2세 : 1개
    • 27세 : 1개
  • 여자
    • 25세 : 1개

Pipeline Aggregation

이거는 MySQL의 어떤 기능이랑 매핑할 수 있을지 딱히 떠오르지 않는다...

공무원 '김공무'는 나이를 역순으로 정렬하고, 페이징 처리를 하고싶다.

SELECT age
FROM Person
GROUP BY age
ORDER BY age DESC
LIMIT 0, 2
GET /person/_search
{
  "size": 0, 
  "aggs": {
    "byAge": {
      "terms": {
        "field": "age"
      },
      "aggs": {
        "sortByAge": {
          "bucket_sort": {
            "sort": [
              { "_key": { "order": "desc" } }
            ],
            "from": 0,
            "size": 2
          }
        }
      }
    }
  }
}


총 데이터는 3개이지만,

ORDER BY age DESC
LIMIT 0, 2

조건에 의해 나이가 높은 2명만 나왔음을 알 수 있다.

Reference
Aggregation : https://esbook.kimjmin.net/08-aggregations
BucketSort: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-sort-aggregation.html

profile
A fast learner.

0개의 댓글