Elasticsearch Aggrigation(집계, 분류)


Aggrigation(집계, 분류)

Elasticsearch는 다음 Aggregation 쿼리를 실행할 수 있다.

먼저 Aggregation 쿼리를 실행해 보기 위해 “demo_agg” 인덱스를 만든다.

demo_agg 색인 생성

POST /_bulk
{ "index" : { "_index" : "demo_agg" , "_id" : "1" }}
{ "text" : "This is Elasticsearch test." , "type" : 1 }
{ "index" : { "_index" : "demo_agg" , "_id" : "2" }}
{ "text" : "Elasticsearch is God." , "type" : 2 }
{ "index" : { "_index" : "demo_agg" , "_id" : "3" }}
{ "text" : "This is a pen." , "type" : 3 }
{ "index" : { "_index" : "demo_agg" , "_id" : "4" }}
{ "text" : "I have a pen." , "type" : 2 }

집계(Metrics)

“demo_agg” 인덱스에 대한 집계를 수행한다. 우선, avg 쿼리를 이용해 값의 평균을 구해 보겠다.

avg 쿼리

GET demo_agg/_search
{
  "size": 0,
  "aggs": {
    "hoge_name": {
      "avg": {
        "field":"type"
      }
    }
  }
}

avg 쿼리 결과

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "hoge_name" : {
      "value" : 2.0
    }
  }
}

value는 2.0d이다. 여기서 평균을 구한 type 의 값은 [1,2,3,2]이므로, 이 평균은 2로 올바른 결과라는 것을 알 수 있다.

또한, "size": 0 은 _search API 의 검색 결과 0개 표시한다. 즉, 표시하지 않겠다는 것을 의마한다. 이 값을 늘리면 평균을 찾는데 사용한 검색 결과를 볼 수 있다.

그 밖에도 이하의 집계를 실시하는 것이 가능하다.

  • sum: 합계 값 받아온다.
  • max: 최대값 받아온다.
  • min: 최소값 받아온다.
  • stats: 위의 모든 값 받아온다.
  • cardinary: 값의 종류를 받아온다. (예를 들면, [1,2,3,2]의 경우는 1,2,3의 3종류가 된다.)

분류(Buckets)

아래와 같이 지정한 조건마다 Buckets를 생성하고, 해당하는 도큐먼트를 Buckets에 넣을 수가 있다. (분류)

범위(range)로 분류

Buckets 생성

GET demo_agg/_search
{
  "size": 0,
  "aggs": {
    "bucket_name": {
      "range": {
        "field":"type",
        "ranges": [
          {
            "from": 0, 
            "to":2
          },
          {
            "from": 2
          }
        ]
      }
    }
  }
}

Buckets 생성 결과

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "bucket_name" : {
      "buckets" : [
        {
          "key" : "0.0-2.0",
          "from" : 0.0,
          "to" : 2.0,
          "doc_count" : 1
        },
        {
          "key" : "2.0-*",
          "from" : 2.0,
          "doc_count" : 3
        }
      ]
    }
  }
}

실행 결과에서 다음과 같이 확인할 수 있다.

  • "type" 필드의 값이 0 이상 2 미만인 Bucket 에는 1개의 도큐먼트가 포함된다. (type=[1])
  • "type" 필드의 값이 2 이상의 Bucket 에는 3개의 문서가 포함된다. (type=[2,3,2])

같은 간격(histgram)으로 분류

이 밖에도 histgram 쿼리를 이용하여 값을 같은 간격으로 분류할 수 있다.

histgram 쿼리

GET demo_agg/_search
{
  "size" : 0 ,
   "aggs" : {
     "bucket_name" : {
       "histogram" : {
         "field" : "type" ,
         "interval" : 1
      }
    }
  }
}

histgram 쿼리 실행 결과

{
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "bucket_name" : {
      "buckets" : [
        {
          "key" : 1.0,
          "doc_count" : 1
        },
        {
          "key" : 2.0,
          "doc_count" : 2
        },
        {
          "key" : 3.0,
          "doc_count" : 1
        }
      ]
    }
  }
}

위와 같이 입력한 간격 값인 1씩 도큐먼트가 각각 Buckets로 분류된 것을 볼 수 있다.