검색엔진 스터디

02장 엘라스틱서치 살펴보기

막이86 2023. 11. 8. 17:23
728x90

엘라스틱서치 실무 가이드 2장을 요약한 내용입니다.

2.1 엘라스틱서치를 구성하는 개념

2.1.1 기본 용어

  • 인덱스
    • 인덱스는 데이터 저장 공간
    • 하나의 인덱스는 하나의 타입
    • 하나의 물리적인 노드에 여러 개의 논리적인 인덱스를 생성 가능
    • 검색시 인덱스 이름으로 문서 데이터를 검색
    • 여러 개의 인덱스를 동시에 검색 가능
    • 인덱스 생성 시 기본적으로 5개의 프라이머리 샤드와 1개의 레플리카 샤드 셋트를 생성
    • 인덱스 이름은 모두 소문자
    • 추가, 수정, 삭제, 검색은 RESTful API로 수행
    • 인덱스가 없는 상태에서 데이터가 추가된다면 데이터를 이용해 인덱스가 자동으로 생성
  • 샤드
    • 색인된 문서는 하나의 인덱스에 저장
    • 인덱스 내부에 색인된 데이터는 물리적인 공간에 여러 개의 파티션으로 나뉘어 구성
      • 파티션을 샤드라고 부른다.
    • 샤드로 문서를 분산 저장하고 있어 데이터 손실 위험을 최소화
  • 타입
    • 인덱스의 논리적 구조를 의미
    • 6.1버전부터는 인덱스당 하나의 타입만 사용
  • 문서
    • 데이터가 저장되는 최소의 단위
    • JSON 포멧으로 데이터가 저장
    • 문서는 다수의 필드로 구성돼 있음
      • 데이터의 형태에 따라 용도에 맞는 데이터 타입을 정의 해야함
    • 중첩 구조를 지원하기 때문에 문서 안에 문서를 지정하는 것이 가능
  • 필드
    • 문서를 구성하기 위한 속성
    • 하나의 필드는 목적에 따라 다수의 데이터 타입을 가질 수 있음
    • ex) 영화 제목을 검색할때 초성을 이용한 검색이 모두 지원되도록 제목 필드는 2개의 데이터 타입을 가져야 한다.
  • 매핑
    • 문서의 필드와 필드의 속성을 정의하고 그에 따른 색인 방법을 정의하는 프로세스
    • 인덱스의 매핑 정보에는 여러 가지 데이터 타입을 지정할 수 있지만 필드명은 중복해서 사용할 수 없다.

2.1.2 노드의 종류

  • 클러스터는 물리적인 노드 인스턴스들의 모임이라 할 수 있다.
  • 클러스터는 모든 노드의 검색과 색인 작업을 과장하는 논리적인 개념
  • 분산 처리를 위해 다양한 형태의 노드들을 조합해서 클러스터를 구성
    • 마스터 노드가 전체적인 클러스터를 관리
    • 데이터 노드가 실제 데이터를 관리
  • 설정에 따라 4가지의 유형의 노드를 제공

마스터 노드

  • 노드 추가와 제거 같은 클러스터 관리
  • 네트워크 속도가 빠르고 지연이 없는 노드를 마스터 노드로 선정
  • 다수의 노드를 마스터 노드로 설정할 수 있지만 결과적으로 하나의 노드만이 마스터 노드로 선출되어 동작
  • conf/elasticsearch.yml 파일 설정 node.master: true node.data: false node.ingest: false search.remote.connect: false

데이터 노드

  • 데이터가 실제로 분산 저장되는 물리적 공간인 샤드가 배치되는 노드
  • 색인 작업은 CPU, 메모리, 스토리지 같은 컴퓨팅 리소스를 많이 소모하기 때문에 리소스 모니터링이 필요
  • 데이터 노드는 가능한 마스터 노드와 분리해서 구성하는 것이 좋다
  • conf/elasticsearch.yml 파일 설정 node.master: false node.data: true node.ingest: false search.remote.connect: false

코디네이팅 노드

  • 데이터 노드, 마스터 노드, 인제스트 노드의 역활을 하지 않고 들어온 요청을 단순히 라운드로빈 방식으로 분산 시켜주는 노드
  • 클러스터 관련 요청은 마스터 노드에 전달
  • 데이터 관련 요청은 데이터 노드에 전달
  • conf/elasticsearch.yml 파일 설정 node.master: false node.data: false node.ingest: false search.remote.connect: false

인제스트 노드

  • 문서의 전처리 작업
  • 스크립트로 전처리 파이프라인을 구성하고 실행 할 수 있다.
conf/elasticsearch.yml 파일 설정

node.master: false
node.data: false
node.ingest: true
search.remote.connect: false

2.1.3 클러스터, 노드, 샤드

[그림 2.2] 클러스터와 노드

  • 하나의 엘라스틱서치 클러스에 노드#1, 노드#2로 총 2개의 물리적 노드가 존재
    • 인덱스의 문서를 조합할 때 마스터 노드를 통해 2개의 노드를 모두 조회해서 각 데이터를 취합 후 결과를 하나로 합쳐서 제공
  • 클러스터에 있는 노드는 실시간으로 추가, 제거가 가능
    • 가용성이나 확장성 측면에서 유연

프라이머리 샤드 3개, 레플리카 샤드 0세트 구성

  • 샤드는 분산된 데이터에 따라 순차적인 번호를 가진다
  • 프라이머리 샤드는 안정성을 위해 하나의 노드에 하나씩 분산 저장
  • 인덱스에 다수의 문서를 색인하면 문서는 3개의 샤드로 골고루 분산 저장

프라이머리 샤드 6개, 레플리카 샤드 0세트 구성

  • 3개의 노드에 프라이머리 샤드 6개가 노드당 2개씩 배치된다.
  • 색인시 6개의 샤드에 데이터가 분산

프라이머리 샤드 3개, 레플리카 샤드 1세트 구성

  • 레플리카 샤드를 1세트를 설정했으므로 3개의 레플리카 샤드가 생성
  • 장애 시 레플리카 샤드를 이용해 샤드를 복구
  • 프라이머리 샤드의 복제본이 존재하기 때문에 물리적인 노드 하나가 죽더라도 나머지 노드 2개가 전체 데이터를 복구할 수 있다.
  • 장애가 발생하면 마스터 노드는 데이터를 재분배하거나 레플리카 샤드를 프라이머리 샤드로 승격시켜 서비스 중단 없는 복구가 가능
  • 장애극복 상황을 염두에 두고 노드와 샤드의 수를 적절히 구성해야 한다.

2.2 엘라스틱서치에서 제공하는 주요 API

API의 종류

  • 인덱스 관리 API: 인덱스 관리
  • 문서 관리 API: 문서의 추가/수정/삭제
  • 검색 API: 문서 조회
  • 집계 API: 문서 통계

스키마리스 기능은 가급적이면 사용하지 말자

  • 스키마리스라는 강력한 기능을 제공
  • 다양한 형태의 비정형 데이터를 하나의 인덱스로 구성 가능
    • 성능과 밀접한 관계가 있으므로 특수한 상황에서만 사용
  • 스키마리스를 사용해야 한다면 데이터 구조 및 검색 방식을 확실히 이해해야 한다.
  • 테스트를 위해 인덱스를 생성하지 않고 데이터를 색인해보자
    • 인덱스 매핑 정보가 정의 되지 않기 때문에 JSON 형식의 키-값을 분석해서 필드명과 각종 속성 정보를 자동으로 생성
    PUT /movie/_doc/1 HTTP/1.1
    
    {
        "movieCd": 1,
        "movieNm": "살아남은 아이",
        "movieNmEn": "Last Child",
        "prdtYear": "2017",
        "openDt": "",
        "typeNm": "장편",
        "prdtStartNm": "기타",
        "nationAlt": "한국",
        "genrAlt": "드라마,가족",
        "repNationNm": "한국",
        "repGenerNm": "드라마"
    }
    
    # 응답
    {
        "_index": "movie",
        "_type": "_doc",
        "_id": "1",
        "_version": 1,
        "result": "created",
        "_shards": {
            "total": 2,
            "successful": 1,
            "failed": 0
        },
        "_seq_no": 0,
        "_primary_term": 1
    }
    
  • movie 인덱스가 생성, _id가 1인 문서가 추가
  • 인덱스가 자동으로 생성되어 세부적인 필드 정보가 매핑되지 않음
    • 특정 단어를 검색할 때 검색 결과에서 누락되는 문제가 발생할 가능성이 높음
  • 인덱스의 구성 정보 조회
    • 기본적으로 모든 필드가 text 타입과 keyword 타입을 동시에 제공하는 멀티필드 기능으로 구성
    • 특정 필드는 text 타입만 필요할 수 있고 keyword 타입만 필요할 수 있다
      • 이런 경우 데이터 공간 낭비
    GET /movie HTTP/1.1
    
    # 응답
    {
        "movie": {
            "aliases": {},
            "mappings": {
                "_doc": {
                    "properties": {
                        "genrAlt": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "movieCd": {
                            "type": "long"
                        },
                        "movieNm": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "movieNmEn": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "nationAlt": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "openDt": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "prdtStartNm": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "prdtYear": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "repGenerNm": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "repNationNm": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "typeNm": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        }
                    }
                }
            },
            "settings": {
                "index": {
                    "creation_date": "1695202798159",
                    "number_of_shards": "5",
                    "number_of_replicas": "1",
                    "uuid": "r5Fu62lSTHWbY9cUQx5R6Q",
                    "version": {
                        "created": "6040399"
                    },
                    "provided_name": "movie"
                }
            }
        }
    }
    
  • 스키마리스는 편리하지만 특수한 상황에 제한적으로 사용
  • 실무에서는 대부분 사용하지 않음
    • 데이터가 대부분 복잡한 구조를 갖기 때문에 검색 품질이 떨어지거나 성능상 문제 발생 할 수 있음
  • 스키마리스를 이용해서 색인한다면 기본적으로 text 타입의 Standard Analyzer를 사용하는 데이터 타입으로 정의될 것이다.
    • 검색을 위해서는 Standard Analyzer가 분리한 토큰 그대로 입력해야함
  • 원하는 결과를 얻기 위해서는 한글 형태소를 분석하는 분석기를 사용하도록 데이터 타입을 직접 정의

<aside> 👉 스키마리스 기능을 사용하고 싶지 않더라도 인덱스를 설정하지 않고 실수로 데이터를 색인하면 엘라스틱서치는 인덱스를 자동 생성한다. 실수를 방지하기 위해 스키마리스 기능을 명시적으로 사용하지 않도록 설정 하는 것이 가능 → action.auto_create_index를 false로 설정

</aside>

2.2.1 인덱스 관리 API

인덱스 생성

  • 인덱스를 생성할 때는 매핑이라는 세부 설정을 이용
  • 매핑은 문서와 문서에 포함된 필드, 필드 타입 등을 세세하게 지정하는 것이 가능한 설정 방식
  • 인덱스 생성시 매핑정보를 추가 가능
  • 한번 생성된 매핑 정보는 변경할 수 없다
    • 잘못 생성했거나 변경해야 하는 경우 데이터를 삭제하고 다시 색인 해야함
  • 단순한 문자열로 저장하고 싶을 경우 keyword 타입을 사용
  • 형태소 분석을 원할 경우 text 타입 사용
PUT /movie HTTP/1.1
{
    "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 2
    },
    "mappings": {
        "_doc": {
            "properties": {
                "movieCd": { "type": "integer" },
                "movieNm": { "type": "text" },
                "movieNmEn": { "type": "text" },
                "prdtYear": { "type": "integer" },
                "openDt": { "type": "date" },
                "typeNm": { "type": "keyword" },
                "prdtStartNm": { "type": "keyword" },
                "nationAlt": { "type": "keyword" },
                "genrAlt": { "type": "keyword" },
                "repNationNm": { "type": "keyword" },
                "repGenerNm": { "type": "keyword" }
            }
        }
    }
}

# 응답
{
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "movie"
}

인덱스 삭제

  • 인덱스를 한번 삭제하면 다시는 복구할 수 없음
  • 삭제는 신중하게
DELETE /movie HTTP/1.1

# 응답
{
    "acknowledged": true
}

2.2.2 문서 관리 API

  • 문서를 색인하고 조회, 수정, 삭제를 지원하는 API
  • 검색을 위한 다양한 검색 패턴을 지원하는 Search API를 별도로 제공
  • 색인된 문서의 ID를 기준으로 한건의 문서를 다뤄야 하는 경우 문서 관리 API를 사용
    • Index API: 한 건의 문서를 색인
    • Get API: 한 건의 문서를 조회
    • Delete API: 한 건의 문서를 삭제
    • Update API: 한 건의 문서를 업데이트
  • 클러스터를 운영하다 보면 다수의 문서를 처리해야 하는 경우도 종종 발생 한다.
    • Multi Get API: 다수의 문서를 조회
    • Bulk API: 대량의 문서를 색인
    • Delete By Query API: 다수의 문서를 삭제
    • Update By Query API: 다수의 문서를 업데이트
    • Reindex API: 인덱스의 문서를 다시 색인

문서 생성

  • 문서의 id를 1을 지정
PUT /movie/_doc/1 HTTP/1.1
{
    "movieCd": 1,
    "movieNm": "살아남은 아이",
    "movieNmEn": "Last Child",
    "prdtYear": "2017",
    "openDt": "2017-10-29",
    "typeNm": "장편",
    "prdtStartNm": "기타",
    "nationAlt": "한국",
    "genrAlt": "드라마,가족",
    "repNationNm": "한국",
    "repGenerNm": "드라마"
}

# 응답
{
    "_index": "movie",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 3,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

문서 조회

  • 문서의 Id를 1로 지정했기 때문에 1을 지정해서 조회
GET /movie/_doc/1 HTTP/1.1

# 응답
{
    "_index": "movie",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "found": true,
    "_source": {
        "movieCd": 1,
        "movieNm": "살아남은 아이",
        "movieNmEn": "Last Child",
        "prdtYear": "2017",
        "openDt": "2017-10-29",
        "typeNm": "장편",
        "prdtStartNm": "기타",
        "nationAlt": "한국",
        "genrAlt": "드라마,가족",
        "repNationNm": "한국",
        "repGenerNm": "드라마"
    }
}

문서 삭제

  • 문서의 ID를 지정하고 DELETE 메서드를 이용해 삭제
DELETE /movie/_doc/1 HTTP/1.1

# 응답
{
    "_index": "movie",
    "_type": "_doc",
    "_id": "1",
    "_version": 2,
    "result": "deleted",
    "_shards": {
        "total": 3,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 1,
    "_primary_term": 1
}

문서의 ID를 지정하지 않고 문서를 생성

  • ID 값을 직접 지정하지 않으면 자동으로 _id값이 생성이 된다.
    • UUID를 통해 무작위로 생성
  • 엘라스틱서치와 데이터베이스의 데이터를 동기화하기 어려움
    • ID값은 데이터베이스 테이블의 식별 값과 맞추는 것이 중요
POST /movie/_doc HTTP/1.1
{
    "movieCd": 1,
    "movieNm": "살아남은 아이",
    "movieNmEn": "Last Child",
    "prdtYear": "2017",
    "openDt": "2017-10-29",
    "typeNm": "장편",
    "prdtStartNm": "기타",
    "nationAlt": "한국",
    "genrAlt": "드라마,가족",
    "repNationNm": "한국",
    "repGenerNm": "드라마"
}

# 응답
{
    "_index": "movie",
    "_type": "_doc",
    "_id": "OjNUtYoBW_DFCGttz4n2",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 3,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

2.2.3 검색 API

  • 엘라스틱서치 검색 API의 사용 방식은 다음과 같이 크게 두 가지로 나뉜다
    • HTTP URI 형태의 파라미터를 URI에 추가해 검색하는 방법
    • RESTful API 방식인 QueryDSL을 사용해 요청 본문에 질의 내용을 추가해 검색하는 방법
  • RESTful 방식이 URI 방식보다 제약사항이 적기 때문에 현업에서는 RESTful 방식을 선호
  • 간단한 표현식이라면 두 가지 형식을 섞어서 사용하는 것도 가능
    • 2017년에 개봉된 영화를 제목 기준으로 정렬
    GET /movie/_doc/_search?q=prdtYear:2017&pretty=true HTTP/1.1
    {
        "sort": {
            "movieCd": {
                "order": "asc"
            }
        }
    }
    
    # 응답
    {
        "took": 30,
        "timed_out": false,
        "_shards": {
            "total": 3,
            "successful": 3,
            "skipped": 0,
            "failed": 0
        },
        "hits": {
            "total": 1,
            "max_score": null,
            "hits": [
                {
                    "_index": "movie",
                    "_type": "_doc",
                    "_id": "1",
                    "_score": null,
                    "_source": {
                        "movieCd": 1,
                        "movieNm": "살아남은 아이",
                        "movieNmEn": "Last Child",
                        "prdtYear": "2017",
                        "openDt": "2017-10-29",
                        "typeNm": "장편",
                        "prdtStartNm": "기타",
                        "nationAlt": "한국",
                        "genrAlt": "드라마,가족",
                        "repNationNm": "한국",
                        "repGenerNm": "드라마"
                    },
                    "sort": [
                        1
                    ]
                }
            ]
        }
    }
    
  • Query DSL을 사용하면 가독성이 높고, JSON 형식으로 다양한 표현이 가능
  • 통계를 위한 집계 쿼리 등 복잡한 쿼리를 작성하려면 Query DSL을 사용하는 것이 좋다

URI 방식의 검색 질의

  • q 파라미터를 사용해 해당 용어와 일치하는 문서만 조회
  • POST /movie/_search?q=장편 HTTP/1.1 # 응답 { "took": 3, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "movie", "_type": "_doc", "_id": "1", "_score": 0.2876821, "_source": { "movieCd": 1, "movieNm": "살아남은 아이", "movieNmEn": "Last Child", "prdtYear": "2017", "openDt": "2017-10-29", "typeNm": "장편", "prdtStartNm": "기타", "nationAlt": "한국", "genrAlt": "드라마,가족", "repNationNm": "한국", "repGenerNm": "드라마" } } ] } }
  • JSON 포멧 해더에는 쿼리가 실행된 총 시간 결과를 보여준다.
  • _shards에서 성공적으로 반환한 샤드의 수와 실패한 샤드의 수를 알수 있다.
  • hits에서 일치하는 문서의 수와 함께 점수가 가장 높은 상위 10개의 문서를 보여준다.
  • time_out 시간이 초과된다면 검색된 내용까지만 결과로 반환
    • 실패한 샤드의 수가 지나치게 많다면 time_out 시간을 적절히 조정해야 한다
  • 특정 필드만 조회하고 싶다면 필드명을 포함해서 요청하면 된다.
  • POST /movie/_search?q=typeNm:장편 HTTP/1.1 { "took": 8, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "movie", "_type": "_doc", "_id": "1", "_score": 0.2876821, "_source": { "movieCd": 1, "movieNm": "살아남은 아이", "movieNmEn": "Last Child", "prdtYear": "2017", "openDt": "2017-10-29", "typeNm": "장편", "prdtStartNm": "기타", "nationAlt": "한국", "genrAlt": "드라마,가족", "repNationNm": "한국", "repGenerNm": "드라마" } } ] } }

Query DSL 방식의 검색 질의

  • URI 방식은 여러 필드를 각기 다른 검색어로 질의하는 것이 어렵다
    • JSON으로 질의하는 것이 좋음
  • JSON 포멧을 이용해 RESTful 방식으로 질의하면 매우복잡한 쿼리도 쉽게 표현할 수 있다
  • POST /movie/_search HTTP/1.1 { "query": { "term": { "typeNm": "장편" } } }
  • 쿼리 구문은 여러 개의 키를 조합해 객체의 키 값으로 사용
  • { "size": 몇 개의 결과를 반환할 지 결정(기본은 10개) "from": 어느 위치부터 반환할지 결정 0부터 시작하면 상위 0~10건의 데이터를 반환(기본은 0) "_source": 특정 필드를 기준으로 정렬 asc, desc로 오름차순, 내림차순 정렬을 지정 가능 "query": { 검색될 조건을 정의 } "filter": { 검색 결과 중 특정한 값을 다시 보여준다. 결과 내에서 재검색할 때 사용하는 기능 중 하나 필터를 사용하게 되면 자동으로 score 값이 정렬되지 않는다. } }

2.2.4 집계 API

  • 엘라스틱서치는 집계 API를 통해 기존의 패싯 API로 하기 어려운 작업을 처리하는 것이 가능
  • 쿼리에 사용되는 집계에 따라 수치를 계산하고 동적으로 카운팅하거나 히스토그램 같은 작업 등도 할 수 있게 바뀜
  • 엘라스틱서치의 집계 API는 각종 통계 데이터를 실시간으로 제공할 수 있는 강력한 기능

데이터 집계

  • _serch API를 사용해 집계 쿼리를 만들고 terms 키워드를 이용해 genreAlt라는 필드의 데이터를 그룹화
    • 버킷(Buckets) 구조 안에 그룹화된 데이터가 포함돼 있다.
    • 엘라스틱서치의 집계가 강력한 이유 중 하나는 버킷 안에 버킷의 결과를 추가할 수 있다
    • 다양한 집계 유형을 결합하거나 중첩, 조합하는 것이 가능
    POST /movie/_search?size=0 HTTP/1.1
    {
        "aggs": {
            "genre": {
                "terms": {
                    "field": "genreAlt"
                }
            }
        }
    }
    
    # 응답
    {
        "took": 23,
        "timed_out": false,
        "_shards": {
            "total": 3,
            "successful": 3,
            "skipped": 0,
            "failed": 0
        },
        "hits": {
            "total": 1,
            "max_score": 0.0,
            "hits": []
        },
        "aggregations": {
            "genre": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": []
            }
        }
    }
    
  • 장르별 국가 형태를 중첩해서 보여주는 집계의 예
  • POST /movie/_search?size=0 HTTP/1.1 { "aggs": { "genre": { "terms": { "field": "genreAlt" } }, "aggs": { "nation": { "terms": { "field": "nationAlt" } } } } } # 응답 { "error": { "root_cause": [ { "type": "named_object_not_found_exception", "reason": "[9:23] unable to parse BaseAggregationBuilder with name [nation]: parser not found" } ], "type": "named_object_not_found_exception", "reason": "[9:23] unable to parse BaseAggregationBuilder with name [nation]: parser not found" }, "status": 400 }

데이터 집계 타입

  • 집계 기능은 현재 4가지 API로 제공
  • 집계 기능은 서로 조합해 사용할 수 있으며 조합해서 매우 강력한 기능을 제공할 수 있다
    • 버킷 집계
      • 집계 중 가장 많이 사용
      • 문서의 필드를 기준으로 버킷을 집계
    • 메트릭 집계
      • 문서에 추출된 값을 가지고 Sum, Max, Min, Avg를 계산
    • 매트릭스 집계
      • 행렬의 값을 합하거나 곱한다
    • 파이프라인 집계
      • 버킷에서 도출된 결과 문서를 다른 필드 값으로 재분류
      • 다른 집계에 의해 생성된 출력 결과를 다시 한번 집계
      • 집계가 패싯보다 강력한 이유
728x90

'검색엔진 스터디' 카테고리의 다른 글

07장 한글 검색 확장 기능  (1) 2023.11.08
05장 데이터 집계  (3) 2023.11.08
04장 데이터 검색  (1) 2023.11.08
03장 데이터 모델링  (1) 2023.11.08
01장 검색 시스템 이해하기  (0) 2023.11.08