집계(aggregation)
- 분산되어 있는 문서를 검색 조건과 일치하는 문서만 모아 수행
- 데이터를 그룹핑하고 통곗값을 얻는 기능
- SQL의 Group By 절과 비슷한 역할
- aggs/aggregations 문법으로 사용하여 집계 정의
- 커스텀 플러그인과 스크립팅으로 집계를 생성하는 것도 가능
- 집계에만 따로 필요한 필터 쿼리를 사용할 수 있음
1. 집계(aggregation) 구조
- aggs 혹은 aggregations의 항목으로 쿼리 사용
2. 집계 종류
2.1 하위 집계
- sub aggregation으로 집계한 결과 문서로 한번 더 집계
- ex) 차량 브랜드로 모델을 집계 (현대 -> 아반떼, 소나타, 그랜저)
- 하위 집계 또는 중첩 횟수가 많아질수록 성능 저하
2.2 중첩 집계
- 동일 레벨의 aggregation으로 여러 개의 집계를 한 번에 수행하는 것이 가능함
- 브랜드, 연식, 색상 등 집계 사용
2.3 집계 유형
- metric (통계나 계산 등에 사용)
- bucket (도큐먼트를 그룹핑하는데 사용)
- nested
- filter
메트릭 집계(metric aggregation)
- 검색 조건에 일치하는 문서들의 수치 연산
- 최댓값, 최솟값, 평균, 합산, 표준편차 등을 계산
- 입력으로 문서 셋을 받고 지정된 필드에 대해 계산된 통계 결과를 생성
- 개별 문서에 연결된 정보가 포함되지 않고 통계 데이터만 포함
- 정수 또는 실수와 같이 숫자 연산을 할 수 있는 값들에 대한 집계
메트릭 집계 | 설명 |
avg | 필드의 평균값 계산 |
min | 필드의 최솟값 계산 |
max | 필드의 최댓값 계산 |
sum | 필드의 총합 계산 |
percentiles | 필드의 백분윗값 계산 |
stats | 필드의 min, max, sum, avg, count(도큐먼트 개수)를 한 번에 볼 수 있음 |
extended_stats | stats의 확장 버전 min, max, sum, avg, count와 더불어 분산, 표준 편차 등을 확인 |
cardinality | 필드의 유니크한 값 개수를 보여줌 |
geo_bounds | 위치의 좌상단, 우하단 좌표 계산 |
geo-centroid | 필드 내부의 위치 정보의 중심점을 계산 |
1. 평균값 구하기(avg)
부연 설명
- 평균 집계(avg)를 이용해 products.base_price 필드의 평균값을 구하는 요청
- 집계명은 각자 원하는 형태로 정할 수 있으며 여기서는 임의로 stats_aggs라는 이름을 사용함
2. 백분위를 구하기(percentiles)
부연 설명
- products.base_rpice 필드의 백분위값을 구하는 요청
- 백분위 집계는 필드의 특정 백분위에 속하는 데이터를 찾아줌
- 중간값은 50, 최댓값은 100
3. 필드의 유니크한 값 개수 확인(cardinality)
부연 설명
- SQL의 distinct_count과 유사
- cardinality는 매우 적은 메모리로 집합의 원소 개수를 추정할 수 있는 HyperLogLog++ 알고리즘 기반으로 동작
- 주 7일이므로 7을 반환
- prceision_threshold 파라미터는 정확도 수치
- 값이 크면 정확도가 올라가는 대신 시스템 리소스를 많이 소모
- 값이 작으면 정확도는 떨어지는 대신 시스템 리소스를 덜 소모
- precision_threshold 값을 변경해보면서 값이 변경되지 않는 임계점을 찾는 것이 이상적
- 기본값은 3,000이며 최대 40,000까지 값을 설정할 수 있음
* 실제로 precision_threshold 값을 100이 아닌 5로 부여할 경우 결과가 7이 아닌 8을 반환
4. terms 쿼리
- 버킷 집계의 일종인 용어 집계(terms)를 사용하면 유니크한 필드 개수와 함께 필드값들을 확인 가능
- doc_count는 각각의 유니크한 필드를 가진 도큐먼트의 개수
- terms 쿼리를 이용하면 필드의 유니크한 데이터 개수와 데이터 종류를 확인할 수 있음
5. 검색 결과 내에서의 집계
부연 설명
- 용어 수준 쿼리인 term 쿼리를 이용해 day_of_week 필드값이 "Monday"인 도큐먼트만을 일차적으로 골라내고
- 해당 문서만을 가지고 query_aggs라는 이름으로 products.base_price 필드의 합을 집계
6. 좌표 범위 계산
부연 설명
- 텍사스 주의 위치 정보
7. Top Hits 집계
- 메트릭 집계로 특정 조건에 맞는 문서들 중 상위 N개의 문서를 반환하는 집계
- 다양한 기준에 따라 정렬된 문서들 중 가장 상위에 위치하는 문서를 선택적으로 조회 가능
- 문서를 특정 필드의 값에 따라 정렬할 수 있으며 이를 통해 가장 관련성이 높거나 최신의 문서 조회 가능
부연 설명
- type 필드를 기준으로 버킷을 생성하고 버킷 내 가장 가격이 높은 차량 정보를 반환
- 이때 brand, model, price 필드만 반환
Bucket 집계
- 검색 조건에 일치하는 도큐먼트들을 특정 기준으로 나눈 다음 나누어진 문서들의 수치를 각각 연산
- 나누어진 단위를 버킷이라고 지칭
- text, keyword 타입으로 버킷 집계를 실행하거나, 히스토그램에 대한 범위 집계 등이 있음
버킷 집계 | 설명 |
histogram | 숫자 타입 필드를 일정 간격으로 분류 |
data_histogram | 날짜/시간 타입 필드를 일정 날짜/시간 간격으로 분류 |
range | 숫자 타입 필드를 사용자가 지정하는 범위 간격으로 분류 |
date_range | 날짜/시간 타입 필드를 사용자가 지정하는 날짜/시간 간격으로 분류 |
terms | 필드에 많이 나타나는 용어(값)들을 기준으로 분류 |
significant_terms | terms 버킷과 유사하나 모든 값을 대상으로 하지 않고 인덱스 내 전체 문서 대비 현재 검색 조건에서 통계적으로 유의미한 값들을 기준으로 분류 |
filters | 각 그룹에 포함시킬 문서의 조건을 직접 지정 이때 조건은 일반적으로 검색에 사용되는 쿼리와 동일 |
1. 히스토그램 집계(histogram aggregation)
- 범위 집계와 마찬가지로 숫자의 범위를 집계
- 일정한 범위 내에 대한 집계
- 간격 내에 속하는 문서들에 대한 집계 수행
- max_buckets 사이즈는 65,536개
부연 설명
- products.base_price 필드의 값을 100 단위로 구분
- key가 0은 필드값이 0~99 사이의 값임을 의미
- doc_count는 버킷에 속한 도큐먼트의 개수
2. 범위 집계(range aggregation)
- 히스토그램 집계는 설정이 간단한 반면 각 버킷의 범위를 동일하게 지정할 수 밖에 없다는 단점 존재
- 특정 구간에 데이터가 몰려있거나 데이터 편차가 큰 경우 모든 데이터를 표현하는데 비효율적일 수 있음
- 범위 집계를 이용하면 각 버킷의 범위를 사용자가 직접 설정 가능
부연 설명
- 데이터가 없거나 한 두개 있던 200~1000 구간은 크게 하나로 병합하고 대신 데이터가 많았던 0~200 구간을 세분화
- 문서가 여러 구간에 걸쳐 있을 경우 doc_count는 중복되서 합산이 됨
3. 용어 집계(terms aggregation)
- 가장 많이 사용되는 버킷 집계
- 단일 term의 값을 기반으로 버킷의 문서를 그룹화
- 필드의 유니크한 값을 기준으로 버킷을 나눌 때 사용
- size 파라미터는 만들어지는 버킷 수를 지정하는데, size를 작성하지 않으면 기본값으로 10이 적용
- size로 지정한 숫자가 생성되는 버킷보다 작은 경우 size로 지정한 버킷만 보이고 나머지 버킷들은 보이지 않음
부연 설명
- day_of_week 필드의 값을 기준으로 도큐먼트 수가 많은 상위 6개의 버킷을 요청
- doc_count_error_upper_bound는 버킷이 잠재적으로 카운트하지 못할 도큐먼트의 수
- sum_other_doc_count는 버킷에는 있지만 size 때문에 보이지 않는 도큐먼트의 수
- 579는 결과에서 빠진 Monday 버킷의 도큐먼트 개수
3.1 용어 집계 파라미터
파라미터 | 설명 |
field | 버킷을 만들기 위해 추출할 필드 지정 |
size | 응답 값으로 표기할 bucket의 개수 |
min_doc_count | 집계할 최소 문서 수(0부터 시작) |
include/exclude | 정규식을 사용하여 유요한 값/제외할 값 정의 |
order | 정렬에 사용할 방법 정의 _count: 버킷 개수가 많은 순 적은 순 정렬 _key: 알파벳 순 정렬 |
3.2 용어 집계가 정확하지 않은 이유
- 용어 집계가 부정확도를 표시하는 이유는 분산 시스템의 집계 과정에서 발생하는 잠재적인 오류 가능성 때문
- 분산 시스템에서는 데이터를 여러 노드에 분산하고 취합하는 과정에서 오류 발생 가능
- Elasticsearch는 샤드에 도큐먼트를 저장하고 이를 분산하는데, size 설정값과 샤드 개수 등에 의해 집계에 오류가 발생할 수 있음
- 집계가 모든 도큐먼트를 가져와 한 번에 집계를 하는 것이 아니라 분산되어 있는 개별 노드단에서 먼저 집계를 하고 그 결과를 취합해 다시 집계를 하기 때문
3.3 용어 집계 정확성 높이기
- 고속 처리를 위한 리소스와 속도 간 트레이드오프의 일환으로 리소스 소비량을 늘리면 정확도를 높일 수 있음
- 용어 집계를 요청할 때 show_term_doc_count_error 파라미터를 추가
- doc_count_error_upper_bound 값을 버킷마다 확인할 수 있음
- 이를 통해 버킷마다 잠재적인 오류 가능성을 확인할 수 있으며 각 버킷마다 doc_count_error_upper_bound 값이 나오고 0이 나오면 오류가 없다는 뜻
- 로컬에서는 샤드 하나만 사용하고 있고 대용량 작업이 아니므로 특별한 오류를 찾을 수 없지만
- 만약 확인 결과 이상값이 나올 경우에는 이를 해결하기 위해 다음과 같이 샤드 크기 파라미터를 늘릴 필요가 있음
- 용어 집계 시 shard_size 파라미터를 이용해 샤드 크기를 늘릴 수 있는데 샤드 크기는 용어 집계 과정에서 개별 샤드에서 집계를 위해 처리하는 개수를 의미
- 샤드 크기를 크게 하면 정확도가 올라가는 대신 리소스 사용량이 올라가 성능은 떨어질 수 있음
- 샤드 크기는 기본적으로 size * 1.5 + 10으로 계산되는데 여기서 size는 버킷의 개수
4. Significant Terms 집계
- 쿼리와 연관이 있는 term을 제안 (연관 검색어)
- 연관 검색어를 만들기 위해서는 로그 데이터 필요
- 사용자 로그를 활용하여 연관관계를 찾을 수 있어 관심 있을 수 있는 상품 추천 가능
- term 간의 관계를 발견
- ex) excape, cr-v, rav4의 type의 연관 관계?
4.1 significant terms 집계 작동방식
- 내부적으로 두 개의 term의 관계를 계산
- 쿼리 또는 상위 집계와 일치하는 문서를 검색한 점수 산정
- 모든 문서의 스코어 합산
- 두 개의 결과 데이터 셋에 점수를 계산하여 결과를 출력
4.2 응답 값
- key: 버킷의 값
- doc_count: 해당 key의 term이 포함된 결과 수
- score: 버킷의 점수(연관 점수)
- bg_count: 해당 term이 포함된 문서 수
5. range 집계
- 수치 데이터나 날짜 데이터를 사용자가 지정한 범위 내에서 집계를 수행하는 다중 버킷 집계
- 추출된 문서에 대해 범위에 해당하는지에 대한 검증 후 범위에 해당하는 문서들에 대해서만 집계 수행
- from, to 속성을 통해 범위 지정
- 사용자가 지정한 범위 내에서 집계를 수행
- 범위에 있는 항목의 가격을 집계, 문서에 포함된 연식을 집계, 날짜의 범위를 지정한 집계 등이 있음
부연 설명
- 가격을 1,000 단위씩 끊어서 문서의 개수를 확인
6. date range 집계
- 숫자 데이터형(integer, float, long, date)에 대한 실행
- 유효한 문자열: yyyy-MM-dd'T'HH:mm:ss / yyyy-MM-dd
- date_range를 통해 범위를 지정할 수 있음
- 날짜를 범위로 지정해서 집계
- 시간 범위를 now로 표현할 수 있음
- now-1h: 현재 시간 기준 한 시간 전
- now-1h/d: 현재 시간에서 1시간을 뺀 시점의 날짜로 이동한 후 그 날짜의 자정으로 설정
- now-1h/M: 현재 시간에서 1시간을 뺀 시점의 날짜로 이동한 후 그 날짜가 속한 월의 첫날로 설정
expression | 의미 |
y | years(연도) |
M | months(월) |
w | weeks(주) |
d | day(일) |
h/H | hours(시) |
m | minutes(분) |
s | seconds(초) |
부연 설명
- 2021년 1월 1일부터 현재까지 현대 브랜드에 대한 문서 개수 집계
Filter 집계
- 특정 필터 조건에 맞는 문서들에 대해서만 집계를 수행하는 방법
- 데이터의 특정 부분에 초점을 맞추고 싶을 때 유용
- 복잡한 조건에 따라 데이터를 세분화하여 분석할 수 있음
- 일치하는 term에 대한 필터의 개수를 실행
- 하나 이상의 쿼리를 사용하여 문서를 필터링하고 필터를 통과한 문서들에 대한 집계 실행
부연 설명
- 현대 브랜드 중 SUV 차량의 가격의 평균과 색상 개수 구하기
- 현대 브랜드 중 SUV 차량으로 일단 필터 집계 후 평균 가격과 색상 개수 구함
Nested 집계
- Object로 묶여 있는 array 형태의 데이터를 array별 데이터를 집계하기 위해 사용
- 검색 시 nested query를 이용하는 것과 동일하게 field aggregation을 하기 위해 nested 사용
- nested 파라미터를 사용하지 않으면 데이터의 집계가 되지 않음
부연 설명
- car-master 인덱스에서 area 필드가 nested 타입인 문서들을 대상으로, state 서브필드가 tx인 문서들을 필터링하여 집계하는 요청
파이프라인 집계
- 이전 결과를 다음 단계에서 이용하는 파이프라인 개념을 차용
- Elastic 파이프라인 집계는 이전 집계로 만들어진 결과를 입력으로 삼아 다시 집계하는 방식
- 이 과정에는 부모 집계와 형제 집계라는 두 가지 유형이 있으며 가장 큰 차이점은 집계가 작성되는 위치
- 부모 집계는 기존 집계 내부에서 작성하고 형제 집계는 기존 집계 외부에서 새로 작성
형제/부모 집계 | 집계 종류 | 설명 |
부모 집계 |
derivative | 기존 집계의 미분을 구함 |
cumulative_sum | 기존 집계의 누적합을 구함 | |
형제 집계 |
min_bucket | 기존 집계 중 최솟값 구함 |
max_bucket | 기존 집계 중 최댓값 구함 | |
avg_bucket | 기존 집계의 평균값 구함 | |
sum_bucket | 기존 집계의 총합 구함 | |
stat_bucket | 기존 집계의 min, max, sum, count, avg를 구함 | |
percentile_bucket | 기존 집계의 백분윗값을 구함 | |
moving_avg | 기존 집계의 이동 평균을 구함 단, 기존 집계는 순차적인 데이터 구조여야 함 |
1. 부모 집계
- 단독으로 사용할 수 없고 반드시 먼저 다른 집계가 있어야 하며 그 집계 결과를 부모 집계가 사용
- 부모 집계는 이전 집계 내부에서 실행
- 결괏값도 기존 집계 내부에서 나타남
부연 설명
- 누적합을 구하는 부모 집계
- 부모 집계를 사용하기 위해서는 입력으로 다른 집계가 필요하므로 여기서는 히스토그램 집계와 합계 집계를 사용
- products.base_price를 100 기준으로 버킷을 나누고 각 버킷에서 taxful_total_price의 합을 구하는 집계
- 부모 집계는 sum_aggs를 입력으로 받아 최종적으로 각 버킷의 누적합을 계산
- 파이프라인 집계는 반드시 버킷 경로(buckets_path)를 입력해야 하는데 입력으로 사용했던 sum_aggs 집계를 적은 것을 확인 가능
2. 자식 집계
- 기존 집계 내부가 아닌 외부에서 기존 집계를 이용해 집계 작업을 수행
부연 설명
- 먼저 term_aggs는 용어 집계로 day_of_week 필드를 기준으로 요일별 버킷을 나누고 상위 2개의 버킷을 생성
- sum_aggs에서 products.base_price 필드의 총합을 구함
- 다음으로 sum_bucket 형제 집계를 이용해 기존 버킷별 합을 구한 집계를 다시 합침
- 파이프라인 집계는 버킷 경로(buckets_path)를 입력해야하는데 버킷 경로에서 '>'는 하위 집계 경로를 나타낼 때 사용
- sum_total_price라는 형제 집계는 기존 집계 내부가 아니라 외부에서 결과를 보여주며 모든 버킷에서 나온 값을 합산한 값
참고
- 패스트 캠퍼스 - 고성능 검색 엔진 구축으로 한 번에 끝내는 Elasticsearch
- 엘라스틱 개발부터 운영까지 (김준영, 정상운 저)
반응형
'Elastic Search' 카테고리의 다른 글
[Elasticsearch] 스크립트 쿼리 (0) | 2024.06.13 |
---|---|
[Elasticsearch] 자동완성 (0) | 2024.06.12 |
[Elasticsearch] 검색 (0) | 2024.06.07 |
[Elasticsearch] 분석기(analyzer) (3) | 2024.06.07 |
[Elasticsearch] 매핑과 인덱스 alias, template (1) | 2024.06.06 |