Elastic Search

[Elasticsearch] 집계

꾸준함. 2024. 6. 9. 18:33

집계(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