ElasticSearch 에서 데이터를 그룹핑 해서 작업할 수 있는 Aggregation
(이하 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"
}
}
MySQL 의 SUM, MAX, MIN 등 집계 함수와 유사하다.
공무원 '김공무' 는 부동산을 가지고 있는 가장 어린 사람을 검색하고자 한다.
SELECT MIN(age)
FROM Person
GET /person/_search
{
"size": 0,
"aggs": {
"byAge": {
"min": {
"field": "age"
}
}
}
}
부동산을 가지고 있는 사람 중 가장 어린 사람은 2살이다.
Mysql 의 GroupBy 와 유사하다.
공무원 '김공무'는, 각 성별별로 부동산을 가지고 있는 사람이 몇명인지 궁금하다.
SELECT gender, COUNT(1)
FROM Person
GROUP BY gender
GET /person/_search
{
"size": 0,
"aggs": {
"byGender": {
"terms": {
"field": "gender"
}
}
}
}
남자가 2개의 부동산을,
여자가 1개의 부동산을 가지고 있음을 알 수 있다.
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"
}
}
}
}
}
}
이거는 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