엘라스틱서치가 로그 분석등에 자주 쓰이는 이유는 사실 검색보다는 집계기능때문이다.

Aggregation을 보통 집계라고 번역하지만 엘라스틱서치의 기능 이름으로 그냥 고유하게 애그리게이션이라고 하는 사람들도 많으므로 앞으로는 애그리게이션이라고 하겠다.

사용법은 다음과 같다. _serachAPI에서 query문과 같은 수준에 지정자 aggregation, 또는 aggs를 명시하고 그 아래 내가 사용할 애그리게이션 이름을 입력한뒤, 애그리게이션 종류와 옵션을 명시한다.

  GET <인덱스명>/_search
{
  "query": {
    … <쿼리 구문> …
  },
  "aggs": {
    "<임의의 aggregation 1>": {
      "<aggregation 종류>": {
        … <aggreagation 구문> …
      }
    },
    "<임의의 aggregation 2>": {
      "<aggregation 종류>": {
        … <aggreagation 구문> …
      }
    }
  }
}

애그리게이션에 종류는 크게 두가지가 있다. Metrics , Bucket 두 종류임. 애그리게이션 구문이나 옵션에 명시는 하지 않지만 숫자나 날짜 필드 갖고 계산을 하는 애그리게이션을 Metrics라고 하고,

범위나 키워드를 가지고 그룹화하는 애그리게이션을 Bucket이라고 한다.

예를 들어보기 위해 아래의 데이터를 먼저 my_stations 인덱스에 넣어보자.

PUT my_stations/_bulk
{"index": {"_id": "1"}}
{"date": "2019-06-01", "line": "1호선", "station": "종각", "passangers": 2314}
{"index": {"_id": "2"}}
{"date": "2019-06-01", "line": "2호선", "station": "강남", "passangers": 5412}
{"index": {"_id": "3"}}
{"date": "2019-07-10", "line": "2호선", "station": "강남", "passangers": 6221}
{"index": {"_id": "4"}}
{"date": "2019-07-15", "line": "2호선", "station": "강남", "passangers": 6478}
{"index": {"_id": "5"}}
{"date": "2019-08-07", "line": "2호선", "station": "강남", "passangers": 5821}
{"index": {"_id": "6"}}
{"date": "2019-08-18", "line": "2호선", "station": "강남", "passangers": 5724}
{"index": {"_id": "7"}}
{"date": "2019-09-02", "line": "2호선", "station": "신촌", "passangers": 3912}
{"index": {"_id": "8"}}
{"date": "2019-09-11", "line": "3호선", "station": "양재", "passangers": 4121}
{"index": {"_id": "9"}}
{"date": "2019-09-20", "line": "3호선", "station": "홍제", "passangers": 1021}
{"index": {"_id": "10"}}
{"date": "2019-10-01", "line": "3호선", "station": "불광", "passangers": 971}

Metrics

가장 흔하게 사용되는 메트릭 애그리게이션은 min, max , sum , avg 임. sum을 사용해보자.

GET my_stations/_search
{
  "size": 0,
  "aggs": {
    "all_passangers": {
      "sum": {
        "field": "passangers"
      }
    }
  }
}

image.png

💡 애그리게이션만 사용할때 size: 0을 지정하면 도큐먼트를 fetch해오는 과정을 생략해 쿼리 성능이 좋아진다. size는 원래 상위 몇개의 결과만 반환할 것인지를 결정하는 옵션임.

애그리게이션은 query문의 영향을 받는다. 아래처럼 match문을 이용해 역 이름이 “강남”인 경우만 sum을 구할 수 있다.

GET my_stations/_search
{
  "query": {
    "match": {
      "station": "강남"
    }
  },
  "size": 0,
  "aggs": {
    "gangnam_passangers": {
      "sum": {
        "field": "passangers"
      }
    }
  }
}