[모니터링 ELK 스택] 11주차-2일차: ElasticSearch 데이터 집계 및 고급 검색

limlim·2025년 3월 4일
0

KDT

목록 보기
15/21
  1. ElasticSearch 집계(Aggregation) 개요
  • Aggregation이란?

    : 검색 결과를 기반으로 통계, 그룹화, 필터링 등의 연산을 수행하는 기능임

    : 일반적인 SQL의 GROUP BY, SUM(), AVG() 같은 집계 함수와 유사하며, 대량의 데이터를 빠르게 분석할 수 있음

  • Aggregation이 필요한 이유

    1) 검색 결과에서 의미 있는 데이터 분석이 가능함

    2) 데이터 시각화를 위한 통계를 생성함

    3) SQL의 GROUP BY 기능과 유사하지만 훨씬 강력한 분석이 가능함

  • Aggregation 유형

    1) Bucket Aggregation
    : 데이터를 그룹화
    : (예제) 제품별 판매량 집계, 고객별 주문 수, 월별 매출 분석

    2) Metric Aggregation
    : 수치 데이터를 계산
    : (예제) 평균 가격, 최대 수량(통계 계산)

    3) Pipeline Aggregation
    : Aggregation 결과를 추가 연산
    : (예제) 이동 평균 계산 (집계 결과 기반 추가 연산)

    4) Matrix Aggregation
    : 여러 개의 필드를 기반으로 통계 분석
    : (예제) 상관관계 분석

  1. ElasticSearch 집계 쿼리 실습

1) 데이터 Indexing

curl -X PUT "http://localhost:9200/sales" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "date": { "type": "date" },
      "product": { "type": "keyword" },
      "price": { "type": "double" },
      "quantity": { "type": "integer" }
    }
  }
}'

2) 샘플 데이터 추가

curl -X POST "http://localhost:9200/sales/_bulk" -H 'Content-Type: application/json' -d'
{"index":{}}
{"date":"2025-01-01","product":"Laptop","price":1500,"quantity":2}
{"index":{}}
{"date":"2025-02-02","product":"Smartphone","price":800,"quantity":5}
{"index":{}}
{"date":"2025-03-03","product":"Tablet","price":600,"quantity":3}
'

-----
curl -X POST "http://localhost:9200/sales/_bulk" -H 'Content-Type: application/json' -d'
{"index":{}}
{"date":"2025-03-04","product":"Laptop","price":1500,"quantity":2}
{"index":{}}
{"date":"2025-03-05","product":"Smartphone","price":800,"quantity":5}
{"index":{}}
{"date":"2025-03-06","product":"Tablet","price":600,"quantity":3}
'

3) 각 유형에 맞게 실습

  1. Aggregation 성능 최적화 팁

1) 필드는 keyword 타입으로 설정
: text 타입은 분석되므로 Aggregation 속도가 느림
: 집계용 필드는 keyword 타입 사용함

2) 필요한 데이터만 가져오기 (size: 0)
: 검색 결과를 필요로 하지 않고 Aggregation 결과만 원할 경우 size: 0을 설정함

3) 필터링을 활용하여 성능 최적화
: filter 쿼리를 사용하면 불필요한 문서들을 제외하고 집계 수행 가능함

  1. filter 특징 및 기본구조
  • 특징
    : 검색 점수를 계산하지 않음
    : 캐싱을 활용하여 성능을 최적화함
    : 집계(Aggregation)와 함께 사용할 때 필수적임

  • 기본 구조
    : 필터링은 bool 쿼리 내에서 "filter": [] 배열로 정의됨

    curl -X GET "http://localhost:9200/sales/_search?size=0" -H 'Content-Type: application/json' -d'
    {
      "query": {
        "bool": {
          "filter": [
            { "term": { "category": "electronics" } },
            { "range": { "price": { "gte": 1000, "lte": 5000 } } }
          ]
        }
      }
    }'
  • must vs filter
    : must -> 검색 점수 계산, 캐싱 안됨, Full-Text 검색
    : filter -> 점수 계산 안함, 캐싱 가능, 정확한 필터링

ElasticSearch 버전 이슈사항

  • 이동 평균 계산(Moving Average) 실행 시 아래 오류 발생

    {"error":{"root_cause":[{"type":"parsing_exception","reason":"Unknown aggregatio
    n type [moving_avg] did you mean [moving_fn]?","line":12,"col":25}],"type":"pars
    ing_exception","reason":"Unknown aggregation type [moving_avg] did you mean [mov
    ing_fn]?","line":12,"col":25,"caused_by":{"type":"named_object_not_found_excepti
    on","reason":"[12:25] unknown field [moving_avg]"}},"status":400
  • 이 문제는 ElasticSearch 버전 이슈로 8.5.0 버전일 경우 아래 스크립트 실행시 오류 발생.

    curl -X GET "http://localhost:9200/sales/_search?size=0" -H 'Content-Type: application/json' -d'
    {
      "aggs": {
        "monthly_sales": {
          "date_histogram": {
            "field": "date",
            "calendar_interval": "month"
          },
          "aggs": {
            "total_sales": { "sum": { "field": "price" } },
            "moving_avg_sales": {
              "moving_avg": { "buckets_path": "total_sales" }
            }
          }
        }
      }
    }'
  • So, 7.8.1 버전으로 다운그레이드

  • But, 8.5.0 버전을 그대로 가져갈 경우 아래 스크립트 실행하면됨

    curl -X GET "http://localhost:9200/sales/_search?size=0" -H 'Content-Type: application/json' -d'
    {
      "aggs": {
        "monthly_sales": {
          "date_histogram": {
            "field": "date",
            "calendar_interval": "month"
          },
          "aggs": {
            "total_sales": { "sum": { "field": "price" } },
            "moving_avg_sales": {
              "moving_fn": {
                "buckets_path": "total_sales",
                "window": 5, 
                "script": "MovingFunctions.unweightedAvg(values)"
              }
            }
          }
        }
      }
    }'
profile
不怕慢,只怕站 개발자

0개의 댓글