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