728x90
버킷 집계는 메트릭 집계와는 다르게 메트릭을 계산하지 않고 버킷을 생성한다. 생성된 버킷은 쿼리와 함께 수행되어 쿼리 결과에 따른 컨텍스트 내에서 집계가 이뤄진다. 집계된 버킷은 또 다시 하위에서 집계를 한번 더 수행해서 집계된 결과에 대해 중첩된 집계를 수행하는 것이 가능하다.
버킷을 생성하는건 집계된 데이터 집합을 메모리에 저장한다는 의미로, 중첩되는 단계가 깊어질수록 메모리 사용량은 점점 더 증가해 성능에 악영향을 줄 수 있다. -> 엘라스틱서치에서는 기본적으로 사용 가능한 최대 버킷 수가 정의되어 있으며, search.max_buckets 값을 변경하는 것으로 조정할 수 있다.
질의 요청 시, 버킷 크기를 -1(전체) 또는 10000 이상의 값으로 지정하면 엘라스틱서치에서는 경고 메시지를 반환한다. 안정적인 집계를 위해서는 성능 측면을 충분히 고려한 후, 집계를 수행해야 한다.
범위 집계
Request
GET /apache-web-log/_search?size=0
{
"aggs": {
"bytes_range": {
"range": {
"field": "bytes",
"ranges": [
{ "from": 1000, "to": 2000 },
//{ "key": "small", "from": 1000, "to": 2000 } // key 지정 가능
{ "from": 2000, "to": 5000 },
{ "from": 5000 } // to 생략하면 "5000 이상" 의미
]
}
}
}
}
Response
"aggregations": {
"bytes_range": {
"buckets": [
{ "key": "1000.0-2000.0", "from": 1000, "to": 2000, "doc_count": 123 },
//{ "key": "small", "from": 1000, "to": 2000, "doc_count": 123 }, //키 지정시 노출
{ "key": "2000.0-5000.0", "from": 2000, "to": 5000, "doc_count": 456 },
{ "key": "5000.0-*", "from": 5000, "doc_count": 78 }
]
}
}
- 사용자가 지정한 범위 내에서 집계를 수행하는 다중 버킷 집계이다.
- 집계를 수행하면 추출된 문서가 범위에 해당하는지 검증하게 되고, 범위에 해당하는 문서들에 대해서만 집계가 수행된다.
- 범위 집계에서는 from과 to 속성을 지정하는데, from을 시작으로 to까지 범위 내에서만 집계가 수행된다.
- to에 지정한 값은 결과에서 제외되므로 주의
- Response 응답
- key: 집계가 수행될 범위 -> key는 기본적으로 범위가 지정되어 있으나, 직접 원하는 정보를 설정할 수도 있음
- from: 범위의 시작 값
- to: 범위의 끝 값(해당 값 제외)
- doc_count: 범위 내의 문서 수
날짜 범위 집계
Request
GET /apache-web-log/_search?size=0
{
"aggs": {
"request_count_with_date_range": {
"date_range": {
"field": "timestamp",
"ranges": [
{
"from": "2015-01-04T05:14:00.000Z",
"to": "2015-01-04T05:16:00.000Z"
},
{
"from": "2015-01-04T05:16:00.000Z",
"to": "2015-01-04T05:18:00.000Z"
}
]
}
}
}
}
Response
"aggregations": {
"request_count_with_date_range": {
"buckets": [
{
"key": "2015-01-04T05:14:00.000Z-2015-01-04T05:16:00.000Z",
"from": 1420348440000,
"from_as_string": "2015-01-04T05:14:00.000Z",
"to": 1420348560000,
"to_as_string": "2015-01-04T05:16:00.000Z",
"doc_count": 120
},
{
"key": "2015-01-04T05:16:00.000Z-2015-01-04T05:18:00.000Z",
"from": 1420348560000,
"from_as_string": "2015-01-04T05:16:00.000Z",
"to": 1420348680000,
"to_as_string": "2015-01-04T05:18:00.000Z",
"doc_count": 98
}
]
}
}
- 날짜 값을 범위로 집계를 수행한다.(from 속성에는 시작 날짜 값을 설정하고, to 속성에는 범위의 마지막 날짜 값을 설정한다)
- 마지막 날짜는 제외
- Response 응답 값
- key: 집계에 대한 날짜 범위
- from: 시작 날짜에 해당하는 밀리초 값
- from_as_string: 시작 날짜의 문자열 표현
- to: 종료 날짜에 해당하는 밀리초 값
- to_as_string: 종료 날짜의 문자열 표현
- doc_count: 날짜 범위에 해당하는 문서 수
히스토리그램 집계
Request
GET /apache-web-log/_search?size=0
{
"aggs": {
"bytes_histogram": {
"histogram": {
"field": "bytes",
"interval": 10000,
//"min_doc_count": 1
}
}
}
}
Response
"aggregations": {
"bytes_histogram": {
"buckets": [
{
"key": 0,
"doc_count": 120
},
{
"key": 10000,
"doc_count": 98
},
{
"key": 20000,
"doc_count": 0
},
{
"key": 30000,
"doc_count": 45
}
]
}
}
- 숫자 범위를 처리하기 위한 집계로, 지정한 수치가 간격을 나타내고, 이 간격의 범위 내에서 집계를 수행한다.
- 문서가 존재하지 않는 구간은 필요하지 않다면 최소 문서 수(min_doc_count)를 설정해서 해당 구간은 제외할 수 있다.
날짜 히스토리그램 집계
Request
GET /apache-web-log/_search?size=0
{
"aggs": {
"daily_request_count": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "minute",
//"format": "yyyy-MM-dd", //응답 format
//"time_zone": "+09:00", //Time Zone(서울)
//"offset": "+3h", //3시간 후부터 집계가 시작되도록
}
}
}
}
Response
"aggregations": {
"daily_request_count": {
"buckets": [
{
"key_as_string": "2015-01-04T05:14:00.000Z",
"key": 1420358040000,
"doc_count": 12
},
{
"key_as_string": "2015-01-04T05:15:00.000Z",
"key": 1420358100000,
"doc_count": 0
},
{
"key_as_string": "2015-01-04T05:16:00.000Z",
"key": 1420358160000,
"doc_count": 5
},
{
"key_as_string": "2015-01-04T05:17:00.000Z",
"key": 1420358220000,
"doc_count": 0
},
{
"key_as_string": "2015-01-04T05:18:00.000Z",
"key": 1420358280000,
"doc_count": 9
},
{
"key_as_string": "2015-01-04T05:19:00.000Z",
"key": 1420358340000,
"doc_count": 0
},
{
"key_as_string": "2015-01-04T05:20:00.000Z",
"key": 1420358400000,
"doc_count": 3
}
]
}
}
- Response 응답
- key_as_string: 지정한 interval 값에 따른 구간 시작 일자(UTC, yyyy-MM-dd HH:mm:ss:SSS 형식)
- key: 1의 날짜에 해당하는 밀리초 값
- doc_count: 해당 구간 문서 수
- 분, 시간, 월, 연도를 구간으로 집계를 수행할 수 있다.
- 구간을 지정하기 위해서는 interval 속성을 사용하면 되며, year, quarter, month, week, day, hour, minute, second 표현식을 사용할 수 있다.
- 더 세밀한 설정은 30m(30분), 1.5h(1시간 반) 같은 값으로 설정할 수 있다.
- format 속성을 통해 반환되는 날짜 형식을 변경할 수 있다.
- 미리 정의된 형식 내에서 지정해야 하며, 공식 매뉴얼을 참고(https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-daterange-aggregation#date-format-pattern)
- 엘라스틱서치는 기본적으로 UTC 기준으로 시간을 제공하며, timeZone 속성을 통해 한국 시간으로 변환된 값을 받을 수 있다.
- offset을 사용하면, 집계 기준이 되는 날짜 값의 시작일자를 조정할 수 있다.
텀즈 집계
Request
GET /apache-web-log/_search
{
"size": 0,
"aggs": {
"request_count_by_country": {
"terms": {
"field": "geoip.country_name.keyword",
"size": 10
}
}
}
}
Response
{
"aggregations": {
"request_count_by_country": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{ "key": "United States", "doc_count": 3974 },
{ "key": "France", "doc_count": 855 },
{ "key": "Germany", "doc_count": 510 },
{ "key": "Sweden", "doc_count": 440 },
{ "key": "India", "doc_count": 428 },
{ "key": "China", "doc_count": 416 }
]
}
}
}
- Response 응답 정리
- doc_count_error_upper_bound: 문서 수에 대한 오류의 상한 선(각 샤드별 계산되는 집계의 성능을 고려해 근사치를 계산하기 때문에 문서 수가 정확하지 않을 수 있다.)
- sum_other_doc_count: 결과에 포함되지 않은 모든 문서 수
- buckets: 최상위 버킷 목록(집계된 결과에서 상위 결과로부터 설정한 size만큼을 반환, 기본 10)
- key: 질의 시 지정한 필드에 해당하는 값
- doc_count: 해당 필드 값과 동일한 문서의 수
- 집계 시 지정한 필드에 대해 빈도수가 높은 텀의 순위로 결과가 반환된다.
- 가장 많이 접속하는 사용자나, 국가별 접근 빈도 등의 집계를 수행가능하다.
- Terms 집계의 필드 값으로 Keyword 데이터 타입을 명시해야 하며, Text 타입 같은 경우 형태소 분석기를 통해 분석하는 과정이 항상 동반되기 때문에 주의가 필요하다.
- sum_other_doc_count는 반환된 결과에 포함되지 않은 집계 결과가 남아있다는 것을 의미하기 때문에 size 속성의 기본 값이 10개보다 많은 결과를 반환받기 위해서는 size 값 지정이 필요하다.
- 집계를 수행할 때는 각 샤드에 집계 요청을 전달하고, 각 샤드가 집계 결과에 대해 정렬을 수행한 자체 뷰를 갖게 되며 이를 병합해 최종 뷰를 만들기 때문에 포함되지 않은 문서가 존재할 경우 집계 결과가 정확하지 않을 수 있다.
- 집계 시, 모든 문서가 포함되지 않은 경우 정확하지 않은 결과가 반환될 수 있음에 주의
- size 값을 늘리면 집계의 정확도가 올라가지만 더 많은 양의 데이터를 담아야 하기 때문에 메모리 사용량과 결과를 계산하는데 드는 처리비용이 늘어난다.
- doc_count_error_upper_bound는 최종 집계 결과에 포함되지 않은 잠재 문서의 수를 의미하며, 이 수치는 각 샤드별 반환된 집계 결과 중 최종 병합 과정에서 선택받지 못한 집계 결과의 가장 마지막 값을 합산한 결과다.
- 현재 집계된 결과보다 해당 값이 높게 나오면 size와 shard_size를 조절해서 정확도를 높이는 것이 좋다
참고
집계와 샤드 크기: 텀즈 집계가 수행될 때 검색 프로세스를 관장하는 노드에서는 각 샤드에게 최상위 버킷을 제공하도록 요청 후 모든 샤드로부터 결과를 받을 때까지 대기하는데, 모든 샤드로부터 결과를 받으면 설정된 size에 맞춰 하나로 병합한 후 Client에게 결과로 전달한다.
각 샤드는 정확성을 위해 size 크기가 아닌 샤드 크기(size * 1.5 + 10)를 사용해 내부적으로 집계를 수행하며, 텀즈 집계의 결과로 받을 텀의 개수를 정확하게 판단할 수 있는 경우에는 shard_size 옵션을 통해 집계할 크기를 직접 지정해 불필요한 연산을 없애고, 정확도를 높일 수 있다.
샤드 크기가 -1로 설정될 경우 엘라스틱서치는 샤드 크기를 자동으로 추정하며, 직접 설정할 경우 size 보다 작은 값으로 설정할 수 없다.
공식 문서: https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-terms-aggregation#search-aggregations-bucket-terms-aggregation-shard-size
728x90
'Elastic Search' 카테고리의 다른 글
| Ch05. 데이터 집계 - 근사값으로 제공되는 집계 연산 (0) | 2025.09.18 |
|---|---|
| Ch05. 데이터 집계 - 파이프라인 집계 (0) | 2025.09.18 |
| Ch05. 데이터 집계 - 메트릭 집계 (0) | 2025.09.18 |
| Ch05. 데이터 집계 - 집계 (0) | 2025.09.18 |
| Ch04. 데이터 검색 - 부가적인 검색 API (0) | 2025.09.14 |