Skip to content

Latest commit

 

History

History
405 lines (326 loc) · 10.8 KB

File metadata and controls

405 lines (326 loc) · 10.8 KB

03. Elasticsearch Aggregation

실습환경

  • Windows 10
  • Elasticsearch 7.10.2
  • Git Bash

01. Aggregation

Aggreation은 데이터를 그룹화하고 간단한 통계 값을 얻을 수 있는 기능입니다. 키바나의 주 기능인 데이터 시각화와 대시보드는 대부분 Aggregation 기반으로 동작하기에, Aggregation을 잘 이해하면 키바나를 더 잘 이용할 수 있습니다.

Aggreation 구조는 아래와 같습니다.

"aggregations" : {
    "<<aggregation name>>" : {
        "<<aggregation type>>" : {
            <<aggregation body>>
        }
        <<, "meta" : { <<meta data body>> } >>
        <<, "aggregations" : { <<sub aggregation>> }>>
    }
    <<, "<<aggregation name2>>" : { << ... >> }>>
}

02. Metric Aggregation

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

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 Type
  • field : 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
    }
  }
}

Max/Min Aggregation

최댓값과 최솟값을 구하는 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 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

지금까지 진행한 내용을 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
    }
  }
}

03. Bucket Aggregation

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 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'

그러면 아래와 같이 chicagola 팀이 있으며, 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
        }
      ]
    }
  }
}

복잡한 Aggirgation

지금까지 학습한 내용을 바탕으로 실제 통계나 분석에서 활용할 법한 복잡한 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) 으로 데이터 분석 강의를 참고하여 작성되었습니다.

상세한 내용이 궁금하시다면 강의 수강을 추천해 드립니다.