로컬에서는 잘 되는데 ☘️

[ElasticSearch] Bucket Aggregation

by youngjun._.


실습 환경

  • 💡 Elasticsearch 7.9.0
  • 💡 Windows 10
  • 💡 Git Bash

Aggregation이란?

간단히 설명하면 ElasticSearch안 Document의 조합을 통해 값을 도출할 때 쓰이는 방법이다.

그 중 Bucket Aggregation은 group by로 이해하면 된다.

그룹으로 특정 지을 때 사용하면 유용하다.

이전 실습에서 만들었던 basketball index를 삭제하고 다시 생성해서

Mapping 부터 시켜보자.

index 삭제하기

curl -XDELETE http://localhost:9200/basketball

index 생성하기

curl -XPUT localhost:9200/basketball


Type Mapping

이제 새로운 index에 데이터를 Mapping시켜보자.

basketball_mapping.json 파일 내용

{
    "record" : {
        "properties" : {
            "team" : {
                "type" : "text",
                "fielddata" : true
            },
            "name" : {
                "type" : "text",
                "fielddata" : true
            },
            "points" : {
                "type" : "long"
            },
            "rebounds" : {
                "type" : "long"
            },
            "assists" : {
                "type" : "long"
            },
            "blocks" : {
                "type" : "long"
            },
            "submit_date" : {
                "type" : "date",
                "format" : "yyyy-MM-dd"
            }
        }
    }
}

recode라는 type 안에 다양한 properties가 있는데

fielddata : true 값은 aggregation할 때 조회할 수 있도록 설정해두었다.

Mapping을 ES에 적용해보자.

$ curl -XPUT 'http://localhost:9200/basketball/record/_mapping?include_type_name=true&pretty' -d @basketball_mapping.json -H 'Content-Type: application/json'

Documents에 Sample data Bulk 하기

Sample data는 아래와 같다.

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"}

위에서 확인한 sample 데이터를 Bulk 하기 위해 다음 명령을 입력하자.

✔ Bulk 하기

$ curl -XPOST http://localhost:9200/_bulk?pretty --data-binary @twoteam_basketball.json -H 'Content-Type: application/json'

JSON 파일은 항상 마지막에 newline을 삽입해주자.


Term Aggregation 실습

Group by Team!

Team으로 그룹을 나눠보자.

terms_aggs.json 파일 내용

{
    "size" : 0,
    "aggs" : {
        "players" : {
            "terms" : {
                "field" : "team"
            }
        }
    }
}

size:0 - 다른 여러 정보를 표시하지 않고 결과만 도출

players - Aggregation name

terms - term Aggregation을 사용한다고 정의


아래 명령어로 Term을 확인해보자

$ curl -XGET 'http://localhost:9200/_search?pretty' --data-binary @terms_aggs.json -H 'Content-Type: application/json'

현재 팀 상황을 표로 나타내면 다음과 같다.

  Doc1 Doc2 Doc3 Doc4
Team Chicago Chicago LA LA

Term Aggregraion 결과 예상했던대로 각 팀이 2개씩 count 된 결과를 확인할 수 있다.

결과

{
  # ... 생략
  "aggregations" : {
    "players" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "chicago",
          "doc_count" : 2
        },
        {
          "key" : "la",
          "doc_count" : 2
        }
      ]
    }
  }
}

복잡한 통계 분석 예제

통계나 분석으로 보기엔 조금 무리가 있어 고려할 사항을 늘려서 실습해보자.

실제 농구경기 처럼 값을 적으면 아래와 같이 자료를 만들 수 있다.

  Doc1 Doc2 Doc3 Doc4
Team Chicago Chicago LA LA
Name Michael Michael Kobe Kobe
Points 30 20 30 40
Rebounds 3 5 2 4
Assists 4 8 8 8
blocks 3 4 5 6

팀을 분류하고, 각 팀 별로 성적을 보는 통계를 만들어보자.

{
    "size" : 0,
    "aggs" : {
        "team_stats" : {
            "terms" : {
                "field" : "team"
            },
            "aggs" : {
                "stats_score" : {
                    "stats" : {
                        "field" : "points"
                    }
                }
            }
        }
    }
}
  • 팀별로 document를 묶어주고
  • 각 팀별로 점수별 stats 통계를 반환
$ curl -XGET 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
          }
        }
      ]
    }
#... 생략

Chicago팀과 LA팀 각각 점수 통계가 나타나는 것을 확인할 수 있다.


본 포스팅은 InflearnELK 스택 (ElasticSearch, Logstash, Kibana) 으로 데이터 분석 강의를 참고하여 작성되었습니다.


'BigData > ElasticSearch' 카테고리의 다른 글

[ElasticSearch] Error Handling  (0) 2020.09.04
[Logstash] logstash 설치하기  (0) 2020.09.03
[ElasticSearch] Metric Aggregation  (0) 2020.09.01
[ElasticSearch] 데이터 조회(Search)  (2) 2020.08.31
[ElasticSearch] Mapping  (0) 2020.08.30

블로그의 정보

개발하는만두

youngjun._.

활동하기