1. Basic
// aggregations 입력
GET <인덱스명>/_search
{
"query": {
… <쿼리 구문> …
},
"aggs": {
"<임의의 aggregation 1>": {
"<aggregation 종류>": {
… <aggreagation 구문> …
}
},
"<임의의 aggregation 2>": {
"<aggregation 종류>": {
… <aggreagation 구문> …
}
}
}
}
2. Metrics Aggregations
Min, Max, Sum, Avg
// my_stations 인덱스의 passangers 필드 합 (sum) 을 가져오는 aggs
GET my_stations/_search
{
"size": 0,
"aggs": {
"all_passangers": {
"sum": {
"field": "passangers"
}
}
}
}
특정 Query의 합계를 가져오는 예제
// stations 값이 "강남" 인 도큐먼트들의 passangers 필드 합 (sum) 을 가져오는 aggs
GET my_stations/_search
{
"query": {
"match": {
"station": "강남"
}
},
"size": 0,
"aggs": {
"gangnam_passangers": {
"sum": {
"field": "passangers"
}
}
}
}
STATS
min, max, sum, avg 값을 모두 가져와야 한다면 다음과 같이 stats aggregation을 사용하면 위 4개의 값 모두와 count 값을 한번에 가져옵니다.
// stats 로 passangers 필드의 min, max, sum, avg 값을 가져오는 aggs
GET my_stations/_search
{
"size": 0,
"aggs": {
"passangers_stats": {
"stats": {
"field": "passangers"
}
}
}
}
Cardinality
필드의 값이 모두 몇 종류인지 분포값을 알려면 Cardinality Aggregation을 사용하면 된다.
- 기본 Text 필드에서는 사용 불가능하다
- 숫자, Keyword, IP 등 다른 필드에서 사용 가능하다.
// line 필드의 값이 몇 종류인지를 가져오는 aggs
GET my_stations/_search
{
"size": 0,
"aggs": {
"uniq_lines ": {
"cardinality": {
"field": "line.keyword"
}
}
}
}
Percentiles, Percentile_ranks
// passangers 필드의 백분위를 가져오는 aggs
GET my_stations/_search
{
"size": 0,
"aggs": {
"pass_percentiles": {
"percentiles": {
"field": "passangers"
}
}
}
}
// passangers 필드의 백분위를 가져오는 aggs 결과
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"pass_percentiles" : {
"values" : {
"1.0" : 971.0000000000001,
"5.0" : 971.0,
"25.0" : 2314.0,
"50.0" : 4766.5,
"75.0" : 5821.0,
"95.0" : 6478.0,
"99.0" : 6478.0
}
}
}
}
필드의 백분위를 지정해서 가져오는것도 가능하다
// passangers 필드의 백분위를 지정해서 가져오는 aggs
GET my_stations/_search
{
"size": 0,
"aggs": {
"pass_percentiles": {
"percentiles": {
"field": "passangers",
"percents": [ 20, 60, 80 ]
}
}
}
}
// passangers 필드의 백분위를 지정해서 가져오는 aggs 결과
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"pass_percentiles" : {
"values" : {
"20.0" : 1667.5,
"60.0" : 5568.0,
"80.0" : 6021.0
}
}
}
}
반대로 값을 지정해서 해당 값이 어느 백분위에 있는지 알아볼수 있다.
// passangers 필드의 값을 지정해서 백분위를 가져오는 aggs
GET my_stations/_search
{
"size": 0,
"aggs": {
"pass_percentile_ranks": {
"percentile_ranks": {
"field": "passangers",
"values": [ 1000, 3000, 6000 ]
}
}
}
}
//passangers 필드의 값을 지정해서 백분위를 가져오는 aggs 결과
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"pass_percentile_ranks" : {
"values" : {
"1000.0" : 10.059568131049886,
"3000.0" : 29.218263576617087,
"6000.0" : 79.1549295774648
}
}
}
}
3. Bucket Aggregations
Bucket aggregation 은 주어진 조건으로 분류된 버킷 들을 만들고, 각 버킷에 소속되는 도큐먼트들을 모아 그룹으로 구분하는 것입니다.
Range
// range aggs 를 이용해서 passangers 필드의 값을 버킷으로 구분
GET my_stations/_search
{
"size": 0,
"aggs": {
"passangers_range": {
"range": {
"field": "passangers",
"ranges": [
{
"to": 1000
},
{
"from": 1000,
"to": 4000
},
{
"from": 4000
}
]
}
}
}
}
// range aggs 를 이용해서 passangers 필드의 값을 버킷으로 구분한 결과
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"passangers_range" : {
"buckets" : [
{
"key" : "*-1000.0",
"to" : 1000.0,
"doc_count" : 1
},
{
"key" : "1000.0-4000.0",
"from" : 1000.0,
"to" : 4000.0,
"doc_count" : 3
},
{
"key" : "4000.0-*",
"from" : 4000.0,
"doc_count" : 6
}
]
}
}
}
aggs 에 설정한 from은 이상 즉 버킷에 포함이고 to는 미만으로 버킷에 포함하지 않습니다.
histogram (Interval)
// histogram aggs 를 이용해서 passangers 필드의 값을 버킷으로 구분
GET my_stations/_search
{
"size": 0,
"aggs": {
"passangers_his": {
"histogram": {
"field": "passangers",
"interval": 2000
}
}
}
}
// histogram aggs 를 이용해서 passangers 필드의 값을 버킷으로 구분한 결과
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"passangers_his" : {
"buckets" : [
{
"key" : 0.0,
"doc_count" : 2
},
{
"key" : 2000.0,
"doc_count" : 2
},
{
"key" : 4000.0,
"doc_count" : 4
},
{
"key" : 6000.0,
"doc_count" : 2
}
]
}
}
}
date_range, date_histogram
// date_histogram 을 이용해서 date 값을 1개월 간격의 버킷으로 구분
GET my_stations/_search
{
"size": 0,
"aggs": {
"date_his": {
"date_histogram": {
"field": "date",
"interval": "month"
}
}
}
}
7.2 버전 부터는 interval 옵션이 사용 종료 권장(depricated) 되고 대신 fixed_interval 과 calendar_interval 으로 나누어 지게 되었습니다. year, quarter, month, week, 같은 달력 기준의 값은 "calendar_interval" : "month" 로 입력을 하고, 30일 처럼 정확히 구분되는 날짜들은 "fixed_interval" : "30d" 로 지정을 해야 합니다.
Terms
terms aggregation 은 keyword 필드의 문자열 별로 버킷을 나누어 집계가 가능합니다. keyword 필드 값으로만 사용이 가능하며 분석된 text 필드는 일반적으로는 사용이 불가능합니다.
// terms 을 이용해서 station 값을 별로 버킷 생성
GET my_stations/_search
{
"size": 0,
"aggs": {
"stations": {
"terms": {
"field": "station.keyword"
}
}
}
}
// terms 을 이용해서 station 값을 별로 버킷 생성한 결과
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"stations" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "강남",
"doc_count" : 5
},
{
"key" : "불광",
"doc_count" : 1
},
{
"key" : "신촌",
"doc_count" : 1
},
{
"key" : "양재",
"doc_count" : 1
},
{
"key" : "종각",
"doc_count" : 1
},
{
"key" : "홍제",
"doc_count" : 1
}
]
}
}
}
4. Sub Aggregations
Bucket Aggregation 으로 만든 버킷들 내부에 다시 "aggs" : { } 를 선언해서 또다른 버킷을 만들거나 Metrics Aggregation 을 만들어 사용이 가능합니다.
// terms aggs 아래에 avg aggs 사용
GET my_stations/_search
{
"size": 0,
"aggs": {
"stations": {
"terms": {
"field": "station.keyword"
},
"aggs": {
"avg_psg_per_st": {
"avg": {
"field": "passangers"
}
}
}
}
}
}
// terms aggs 아래에 avg aggs 사용 결과
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"stations" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "강남",
"doc_count" : 5,
"avg_psg_per_st" : {
"value" : 5931.2
}
},
{
"key" : "불광",
"doc_count" : 1,
"avg_psg_per_st" : {
"value" : 971.0
}
},
{
"key" : "신촌",
"doc_count" : 1,
"avg_psg_per_st" : {
"value" : 3912.0
}
},
{
"key" : "양재",
"doc_count" : 1,
"avg_psg_per_st" : {
"value" : 4121.0
}
},
{
"key" : "종각",
"doc_count" : 1,
"avg_psg_per_st" : {
"value" : 2314.0
}
},
{
"key" : "홍제",
"doc_count" : 1,
"avg_psg_per_st" : {
"value" : 1021.0
}
}
]
}
}
}
// terms aggs 아래에 하위 terms aggs 사용
GET my_stations/_search
{
"size": 0,
"aggs": {
"lines": {
"terms": {
"field": "line.keyword"
},
"aggs": {
"stations_per_lines": {
"terms": {
"field": "station.keyword"
}
}
}
}
}
}
// terms aggs 아래에 하위 terms aggs 사용 결과
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"lines" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "2호선",
"doc_count" : 6,
"stations_per_lines" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "강남",
"doc_count" : 5
},
{
"key" : "신촌",
"doc_count" : 1
}
]
}
},
{
"key" : "3호선",
"doc_count" : 3,
"stations_per_lines" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "불광",
"doc_count" : 1
},
{
"key" : "양재",
"doc_count" : 1
},
{
"key" : "홍제",
"doc_count" : 1
}
]
}
},
{
"key" : "1호선",
"doc_count" : 1,
"stations_per_lines" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "종각",
"doc_count" : 1
}
]
}
}
]
}
}
}
5. Pipeline Aggregations
// passangers 의 값을 입력으로 받는 cumulative_sum aggs 실행
GET my_stations/_search
{
"size": 0,
"aggs": {
"months": {
"date_histogram": {
"field": "date",
"interval": "month"
},
"aggs": {
"sum_psg": {
"sum": {
"field": "passangers"
}
},
"accum_sum_psg": {
"cumulative_sum": {
"buckets_path": "sum_psg"
}
}
}
}
}
}
// passangers 의 값을 입력으로 받는 cumulative_sum aggs 실행 결과
{
"took" : 7,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"months" : {
"buckets" : [
{
"key_as_string" : "2019-06-01T00:00:00.000Z",
"key" : 1559347200000,
"doc_count" : 2,
"sum_psg" : {
"value" : 7726.0
},
"accum_sum_psg" : {
"value" : 7726.0
}
},
{
"key_as_string" : "2019-07-01T00:00:00.000Z",
"key" : 1561939200000,
"doc_count" : 2,
"sum_psg" : {
"value" : 12699.0
},
"accum_sum_psg" : {
"value" : 20425.0
}
},
{
"key_as_string" : "2019-08-01T00:00:00.000Z",
"key" : 1564617600000,
"doc_count" : 2,
"sum_psg" : {
"value" : 11545.0
},
"accum_sum_psg" : {
"value" : 31970.0
}
},
{
"key_as_string" : "2019-09-01T00:00:00.000Z",
"key" : 1567296000000,
"doc_count" : 3,
"sum_psg" : {
"value" : 9054.0
},
"accum_sum_psg" : {
"value" : 41024.0
}
},
{
"key_as_string" : "2019-10-01T00:00:00.000Z",
"key" : 1569888000000,
"doc_count" : 1,
"sum_psg" : {
"value" : 971.0
},
"accum_sum_psg" : {
"value" : 41995.0
}
}
]
}
}
}
서로 다른 버킷에 있는 값들도 bucket_path에 > 기호를 이용해서 "부모>자녀" 형태로 지정이 가능합니다. 다음은 sum_bucket 을 이용해서 mon>sum_psg 버킷에 있는 passangers 필드값의 합을 구하는 예제입니다.
// 다른 부모의 자녀 버킷에 있는 필드를 입력으로 받는 pipeline aggs
GET my_stations/_search
{
"size": 0,
"aggs": {
"mon": {
"date_histogram": {
"field": "date",
"interval": "month"
},
"aggs": {
"sum_psg": {
"sum": {
"field": "passangers"
}
}
}
},
"bucket_sum_psg": {
"sum_bucket": {
"buckets_path": "mon>sum_psg"
}
}
}
}
// 다른 부모의 자녀 버킷에 있는 필드를 입력으로 받는 pipeline aggs 실행 결과
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"mon" : {
"buckets" : [
{
"key_as_string" : "2019-06-01T00:00:00.000Z",
"key" : 1559347200000,
"doc_count" : 2,
"sum_psg" : {
"value" : 7726.0
}
},
{
"key_as_string" : "2019-07-01T00:00:00.000Z",
"key" : 1561939200000,
"doc_count" : 2,
"sum_psg" : {
"value" : 12699.0
}
},
{
"key_as_string" : "2019-08-01T00:00:00.000Z",
"key" : 1564617600000,
"doc_count" : 2,
"sum_psg" : {
"value" : 11545.0
}
},
{
"key_as_string" : "2019-09-01T00:00:00.000Z",
"key" : 1567296000000,
"doc_count" : 3,
"sum_psg" : {
"value" : 9054.0
}
},
{
"key_as_string" : "2019-10-01T00:00:00.000Z",
"key" : 1569888000000,
"doc_count" : 1,
"sum_psg" : {
"value" : 971.0
}
}
]
},
"bucket_sum_psg" : {
"value" : 41995.0
}
}
}
'Elasticsearch (ELK) > Elasticsearch' 카테고리의 다른 글
8-3. 멀티 필드 - Multi Field (0) | 2020.05.29 |
---|---|
8-2. Settings & Mappings - Mappings (0) | 2020.05.29 |
8-1. Settings & Mappings - Settings (0) | 2020.05.29 |
7-6 형태소 분석 - Stemming (0) | 2020.05.28 |
7-5. 데이터 색인과 텍스트 분석(실전) - Token Filter (0) | 2020.05.28 |