Tech 기록지/Elastic Stack
[ElasticStack-16] Terms query & Aggregation (sum, avg)
Lio Grande
2020. 6. 12. 13:37
Elasticsearch로 다음과 같은 항목들이 저장되어 있다고 가정하자.
subject | score |
국어 | 100 |
영어 | 90 |
수학 | 80 |
과학 | 70 |
이 때 국여, 영어, 수학에 대한 score 합(sum)과 평균(avg)를 Query를 통하여 구하고 싶다면 다음과 같은 방식으로 표현할 수 있다.
GET index/_search
{
"query": {
"terms": {
"subject": [
"국어",
"영어",
"수학"
]
}
},
"aggs": {
"sum_score": {
"sum": {
"script": {
"source": "doc.score.value"
}
}
},
"avg_score": {
"avg": {
"script": {
"source": "doc.score.value"
}
}
}
}
}
쿼리의 결과값은 다음과 같은 패턴으로 나온다.
{
"took":1,
"timed_out" : false,
### ... 중략 ... ###
"hits" : {
"hits" : [
{
### "subject" : "국어"에 대한 index 및 기타 정보 ###
},
{
### "subject" : "영어" ... ###
},
{
### "subject" : "수학" ... ###
}
]
},
"aggregations": {
"sum" : {
"value" : 12313 ## 값은 임의 표기
},
"avg" : {
"value" : 1351351.3123 ## 값은 임의 표기
}
}
}
**** 추가사항 ****
특정필드를 기준으로 sum, avg 등을 하고 싶다면 다음과 같은 옵션을 추가하자.
### file_name 필드를 기준으로 sum, avg 등을 하고 싶은 경우
GET index/_search
{
"query": {
"terms": {
"subject": [
"국어",
"영어",
"수학"
]
}
},
"aggs": {
"aggregation_naming_1": {
"filter": {
"terms": {
"field": "FIELD_VALUE"
}
},
"aggs": {
"aggregation_naming_2": {
"sum": {
"script": "doc.score.value"
}
}
}
}
}
}
만약, ES의 형태소 분석 점수(max_score)가 필요하지 않다면 다음과 같이 필터를 적용하자.
### file_name 필드를 기준으로 sum, avg 등을 하고 싶은 경우
GET index/_search
{
"query": {
"bool": {
"filter": [
{
"terms": {
"subject": [
"국어",
"영어",
"수학"
]
}
}
]
}
},
"sort": [
"subject": {
"order": "desc"
},
"score": {
"order": "desc"
}
],
"aggs": {
"sum_score": {
"script": "doc.score.value"
}
}
}
}