- Windows 10
- Elasticsearch 7.10.2
- Git Bash
Aggreation은 데이터를 그룹화하고 간단한 통계 값을 얻을 수 있는 기능입니다. 키바나의 주 기능인 데이터 시각화와 대시보드는 대부분 Aggregation 기반으로 동작하기에, Aggregation을 잘 이해하면 키바나를 더 잘 이용할 수 있습니다.
Aggreation 구조는 아래와 같습니다.
"aggregations" : {
"<<aggregation name>>" : {
"<<aggregation type>>" : {
<<aggregation body>>
}
<<, "meta" : { <<meta data body>> } >>
<<, "aggregations" : { <<sub aggregation>> }>>
}
<<, "<<aggregation name2>>" : { << ... >> }>>
}
Metric Aggregation
은 평균 구하기, 최댓값/최솟값 구하기 등 산술을 할 때 사용됩니다.
Metric Aggregation 실습에서는 Search 실습에서 사용했던 simple_basketball.json 데이터를 사용할 예정입니다. 해당 데이터가 Elasticsearch에 존재하지 않으면, 아래 명령어를 통해 Bulk 하길 바랍니다.
curl -X POST http://localhost:9200/_bulk?pretty --data-binary @simple_basketball.json -H 'Content-Type:application/json'
AVG Aggregation
을 통해 평균을 구할 수 있습니다. 실습에서는 points
필드의 평균을 구하라고 설정한 json 파일인 avg_points_aggs.json
을 사용할 예정입니다.
{
"size": 0,
"aggs": {
"avg_score": {
"avg": {
"field": "points"
}
}
}
}
그 전에 avg_points_aggs.json
을 통해 AVG Aggrigation
작성법을 살펴보려고 합니다.
"size" : 0
: 결과 값으로 보고 싶은 값만 출력aggs
:aggrigations
라고 작성해도 되며, 작성한 그대로 Aggrigation을 의미avg_score
: Aggrigation Name. (Custom 설정)avg
: 평균을 의미하는 Aggrigation Typefield
: Aggrigation 하려는 필드
아래 명령어를 통해 실행시켜봅시다.
curl -X GET '{elasticsearch address}/_search' --data-binary @{파일명}.json -H 'Content-Type:application/json'
# e.g
curl -X GET http://localhost:9200/_search?pretty --data-binary @avg_points_aggs.json -H 'Content-Type:application/json'
document에 존재하는 points는 각각 30과 20이며, 평균은 25입니다. 실행 결과를 통해, 예상한 평균인 25를 출력하는 것을 확인할 수 있습니다.
{
// ... 앞의 내용 생략
"aggregations": {
"avg_score": {
"value": 25.0
}
}
}
최댓값과 최솟값을 구하는 Aggrigation도 실습해봅시다.
아래 max_points_aggs.json
을 통해 최댓값을 먼저 구해보려고 합니다.
{
"size": 0,
"aggs": {
"max_score": {
"max": {
"field": "points"
}
}
}
}
그 다음 파일을 변경하여 실행합니다.
curl -X GET http://localhost:9200/_search?pretty --data-binary @max_points_aggs.json -H 'Content-Type:application/json'
그러면 최댓값이 30으로 구해진 것을 확인할 수 있습니다.
{
// ... 앞의 내용 생략
"aggregations": {
"max_score": {
"value": 30.0
}
}
}
이번에는 최솟값을 구해봅시다. max_points_aggs.json
의 max를 모두 min으로 변경한 min_points_aggs.json
의 내용은 아래와 같습니다.
{
"size": 0,
"aggs": {
"min_score": {
"min": {
"field": "points"
}
}
}
}
max를 min으로 변경하여 실행합니다.
curl -X GET http://localhost:9200/_search?pretty --data-binary @min_points_aggs.json -H 'Content-Type:application/json'
그러면 최솟값이 20으로 구해진 것을 확인할 수 있습니다.
{
// ... 앞의 내용 생략
"aggregations": {
"min_score": {
"value": 20.0
}
}
}
이번에는 합을 구하는 SUM Aggrigation을 사용해봅시다.
이전에 진행했던 것과 같이, 먼저 sum_points_aggs.json
을 작성합니다.
{
"size" : 0,
"aggs" : {
"sum_score" : {
"sum" : {
"field" : "points"
}
}
}
}
그 다음, 위에서 작성한 파일을 사용하여 명령어를 실행합니다.
curl -X GET http://localhost:9200/_search?pretty --data-binary @sum_points_aggs.json -H 'Content-Type:application/json'
그러면 document의 points를 합산한 값인 50을 출력하는 것을 확인할 수 있습니다.
{
// ... 앞의 내용 생략
"aggregations" : {
"sum_score" : {
"value" : 50.0
}
}
}
지금까지 진행한 내용을 STATS Aggrigation
을 통해 한 번에 출력할 수 있습니다.
Aggrigation을 위한 stats_points_aggr.json
은 아래와 같이 작성합니다.
{
"size" : 0,
"aggs" : {
"stats_score" : {
"stats" : {
"field" : "points"
}
}
}
}
그 다음, 지금까지 사용한 명령어의 파일명을 변경하여 실행합니다.
curl -X GET http://localhost:9200/_search?pretty --data-binary @stats_points_aggs.json -H 'Content-Type:application/json'
그러면 아래와 같이 결과에 avg
, min
, max
, sum
이 포함되어 있는 것을 확인할 수 있습니다.
{
// ... 앞의 내용 생략
"aggregations" : {
"stats_score" : {
"count" : 2,
"min" : 20.0,
"max" : 30.0,
"avg" : 25.0,
"sum" : 50.0
}
}
}
Bucket Aggrigation
은 특정 기준에 맞춰서 도큐먼트를 그룹핑하는 역할을 합니다. RDB의 groupby
와 유사하다고도 볼 수 있습니다. 여기서 버킷은 도큐먼트가 분할되는 단위로 나뉜 각 그룹을 의미합니다.
이번 실습에서는 새로운 basketball
인덱스를 활용할 예정입니다. 위 실습을 진행했다면, 기존의 basketball
인덱스를 제거한 다음 진행하길 바랍니다.
curl -X DELETE http://localhost:9200/basketball
Document를 저장할 basketball
인덱스를 먼저 생성합니다.
curl -X PUT http://localhost:9200/basketball
그 다음 basketball_mapping.json 파일을 생성한 인덱스에 Mapping 합니다.
curl -X PUT 'http://localhost:9200/basketball/record/_mapping?include_type_name=true&pretty' -d @basketball_mapping.json -H 'Content-Type: application/json'
그 다음 두 개의 팀에 대한 샘플 데이터인 twoteam_basketball.json
을 Bulk합니다.
curl -X POST http://localhost:9200/_bulk?pretty --data-binary @twoteam_basketball.json -H 'Content-Type: application/json'
twoteam_basketball.json
내용은 다음과 같습니다.
{ "index" : { "_index" : "basketball", "_type" : "record", "_id" : "1" } }
{"team" : "Chicago","name" : "Michael Jordan", "points" : 30,"rebounds" : 3,"assists" : 4, "blocks" : 3, "submit_date" : "1996-10-11"}
{ "index" : { "_index" : "basketball", "_type" : "record", "_id" : "2" } }
{"team" : "Chicago","name" : "Michael Jordan","points" : 20,"rebounds" : 5,"assists" : 8, "blocks" : 4, "submit_date" : "1996-10-13"}
{ "index" : { "_index" : "basketball", "_type" : "record", "_id" : "3" } }
{"team" : "LA","name" : "Kobe Bryant","points" : 30,"rebounds" : 2,"assists" : 8, "blocks" : 5, "submit_date" : "2014-10-13"}
{ "index" : { "_index" : "basketball", "_type" : "record", "_id" : "4" } }
{"team" : "LA","name" : "Kobe Bryant","points" : 40,"rebounds" : 4,"assists" : 8, "blocks" : 6, "submit_date" : "2014-11-13"}
필드별 집계를 하는 Terms Aggrigation
실습을 해봅시다.
먼저 실습에서 활용할 terms_aggs.json
을 작성합니다.
{
"size" : 0,
"aggs" : {
"players" : {
"terms" : {
"field" : "team"
}
}
}
}
그 다음 Metrix Aggrigation
실습에서 사용했던 명령어에서 파일명을 변경하여 실행합니다.
curl -X GET 'http://localhost:9200/_search?pretty' --data-binary @terms_aggs.json -H 'Content-Type: application/json'
그러면 아래와 같이 chicago
와 la
팀이 있으며, documents는 2개 있다는 것을 확인할 수 있습니다.
{
// ... 앞의 내용 생략
"aggregations" : {
"players" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "chicago",
"doc_count" : 2
},
{
"key" : "la",
"doc_count" : 2
}
]
}
}
}
지금까지 학습한 내용을 바탕으로 실제 통계나 분석에서 활용할 법한 복잡한 Aggrigation
에 대한 실습을 진행해봅시다.
이번 실습에서는 각 팀별 점수에 점수에 대한 통계를 확인해보려 합니다. 이를 위한 stats_by_team.json
을 아래와 같습니다.
{
"size" : 0,
"aggs" : {
"team_stats" : {
"terms" : {
"field" : "team"
},
"aggs" : {
"stats_score" : {
"stats" : {
"field" : "points"
}
}
}
}
}
}
그 다음 명령어를 실행해 결과를 확인해봅시다.
curl -X GET http://localhost:9200/_search?pretty --data-binary @stats_by_team.json -H 'Content-Type: application/json'
그러면 아래와 같이 각 팀에 대한 점수 통계를 볼 수 있습니다.
{
// ... 앞의 내용 생략
"aggregations" : {
"team_stats" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "chicago",
"doc_count" : 2,
"stats_score" : {
"count" : 2,
"min" : 20.0,
"max" : 30.0,
"avg" : 25.0,
"sum" : 50.0
}
},
{
"key" : "la",
"doc_count" : 2,
"stats_score" : {
"count" : 2,
"min" : 30.0,
"max" : 40.0,
"avg" : 35.0,
"sum" : 70.0
}
}
]
}
}
}
본 게시글은 ELK 스택 (ElasticSearch, Logstash, Kibana) 으로 데이터 분석 강의를 참고하여 작성되었습니다.
상세한 내용이 궁금하시다면 강의 수강을 추천해 드립니다.