OpenSearch 에 대해 공부하기 위해 조사한 사항. GPT 4.1
질문
elasticsearch 와 opensearch 에 대해 공부하고 싶은데 검색엔진에 대해 내가 피상적으로 알고 있는 사항을 얘기할 테니 맞는지 틀린건 어떤건지 알려줘. 또한 검색엔진에 대해 알아야 할 기반 지식도 같이 알려줘.
검색엔진은 비정형 텍스트 데이터를 전문 검색하기 위해 일반적으로 사용 됨.
또는 여러 종류의 데이터를 구분해서 입력 할 수 있으며 메타데이터 설정을 해야 함. 예를 들어 상품 검색을 하기 위해서 ‘_product’ 인덱스를 만들고 [가격, 상품설명, 성별, 카테고리 이름]으로 구성된 데이터를 입력 할 수 있어.
이렇게 구성된것은 ranking 함수를 사용해서 결과 정렬에 이용 할 수 있어.
전문 검색은 전문검색을 위한 알고리즘을 이용해 순위를 생성하고 인덱스를 생성해. 전문검색의 대표적인 알고리즘은 BM25 야.
아주 정확하게 개념을 잡으셨고, 일부는 더 깊게 들어갈 수 있습니다. 말씀해주신 내용을 사실 여부와 근거
를 중심으로 하나씩 피드백하고, 검색엔진(특히 Elasticsearch, OpenSearch)에서 반드시 알아야 할 기반 지식
도 추가로 정리해드립니다.
5. Query / Filter
• Query: 점수(스코어)가 붙는 검색 (ex: “~와 비슷한 문서”)
• Filter: 스코어 없음, 딱 맞는 값만 필터링 (ex: 가격 < 10000)
1.
“검색엔진은 비정형 텍스트 데이터를 전문 검색하기 위해 일반적으로 사용 됨.”
맞음.
검색엔진(Elasticsearch/OpenSearch 등)은 로그, 문서, 게시글 등 비정형 텍스트 데이터의 “전문(full-text)” 검색을 위해 널리 쓰입니다.
참고: Elastic 공식문서
비정형
: 스키마가 고정되어 있지 않거나, 텍스트 기반의 데이터(문장, 단락 등).
2.
“여러 종류의 데이터를 구분해서 입력할 수 있으며 메타데이터 설정을 해야 함.”
맞음.
인덱스는 ‘테이블’과 유사한 개념이고, 각 인덱스에는 다양한 필드(메타데이터 포함)를 가질 수 있습니다.
상품 인덱스에 [가격, 상품설명, 성별, 카테고리] 등 원하는 필드 구성 가능.
필드마다 타입을 지정(예: keyword, text, integer, date 등)해야 검색 성능에 최적화됨.
3.
“이렇게 구성된 것은 ranking 함수를 사용해서 결과 정렬에 이용 할 수 있어.”
맞음.
“랭킹 함수”는 사용자의 질의(query)에 얼마나 잘 맞는지를 “점수(score)”로 계산하고, 이 점수에 따라 결과를 정렬합니다.
기본 랭킹 알고리즘은 BM25.
필요하다면,
사용자 정의 랭킹(score script)
도 가능.
4.
“전문 검색은 전문검색을 위한 알고리즘을 이용해 순위를 생성하고 인덱스를 생성해.”
절반만 맞음.
인덱스 생성과 랭킹 알고리즘은 분리된 개념입니다.
인덱스 생성:
데이터를 빠르게 찾기 위한 자료구조(역색인, inverted index)를 만드는 것.랭킹 알고리즘:
검색 시 질의와 문서의 유사도(점수)를 계산해 결과를 정렬하는 것.실제로는 인덱싱 단계에서 역색인을 만들고, 검색 단계에서 BM25(혹은 다른 알고리즘)를 써서 랭킹.
5.
“전문검색의 대표적인 알고리즘은 BM25 야.”
맞음.
BM25는 현재까지 실무에서 가장 널리 쓰이는
“문서-쿼리 간 유사도 점수”
산정 알고리즘입니다.Elasticsearch, OpenSearch의 기본(full-text) 스코어링 알고리즘.
검색엔진(Elasticsearch, OpenSearch) 기초적으로 알아야 할 개념
Index / Document / Field
Index:
데이터 집합(=RDB의 테이블).Document:
한 개의 레코드/row.Field:
Document의 속성(=RDB의 컬럼).
Mapping (매핑)
각 필드의 데이터 타입 및 인덱싱 옵션 정의.
text(전문검색용), keyword(정확 매칭용), integer, date 등.
RDBMS의 Schema 에 대응
Inverted Index (역색인)
텍스트를 빠르게 검색하기 위한 핵심 자료구조.
각 “단어”가 어디 문서에 있는지 역방향으로 매핑.
Analyzer / Tokenizer
텍스트를 “토큰(단어)” 단위로 쪼개고, 소문자화, 불용어(stopword) 제거 등 전처리.
한글, 영어, 기타 언어마다 Analyzer가 다름.
예시: “여성 청바지” → [여성, 청바지]로 분해
Query / Filter
Query:
점수(스코어)가 붙는 검색 (ex: “~와 비슷한 문서”)Filter:
스코어 없음, 딱 맞는 값만 필터링 (ex: 가격 < 10000)둘의 차이를 이해하는 것이 중요
Scoring (BM25 등)
검색 결과의 순위를 결정하는 알고리즘 (BM25, TF-IDF 등)
쿼리와 문서의 관련도를 수치화
Aggregation (집계)
- SQL의 GROUP BY와 유사. 카테고리별 상품 수, 가격대 분포 등 집계 질의 지원
분산 구조
- 데이터 샤딩(shard), 레플리카(replica) 구조. 수평 확장 지원
OpenSearch vs Elasticsearch
OpenSearch는 AWS 주도로 만들어진 Elasticsearch 오픈소스 분기(fork).
대부분의 기본 사용법은 동일하나, 플러그인 및 일부 기능에서 차이 존재.
참고: 공식 FAQ
실용 예시
상품 인덱스 생성 (Elasticsearch 예시, OpenSearch도 거의 동일)
1 | PUT /products |
상품 검색 예시 (쿼리 + 필터)
1 | POST /products/_search |
추천 학습 자료
요약
전체적으로 개념 잘 잡으셨고,
인덱스 구조와 랭킹 함수의 차이
만 조금 보완하면 더 완벽.반드시 알아야 할 기반 개념은
역색인, 매핑, analyzer, query/filter, scoring
등.Elasticsearch와 OpenSearch는 거의 동일하지만, 오픈소스 분기로 약간의 차이 존재.
더 구체적으로 궁금한 주제(예: 한글 분석기, 쿼리 최적화, 랭킹 커스터마이즈 등) 있으면 추가로 질문 주셔도 됩니다.
추가 질문
1. 언어별 형태소 분석기의 대표적인 예(한글, 영어, 일본어, 범용)
2. 형태소 분석기를 통한 데이터를 입력해야 하는지, 데이터를 입력 할 때 형태소 분석기를 지정하면 되는지?
3. 쿼리 최적화가 RDBMS와 다른점은?
1. 언어별 형태소 분석기의 대표적인 예
형태소 분석기(Morphological Analyzer)
는 언어마다 다릅니다.
Elasticsearch/OpenSearch에서 자주 쓰이는 대표적인 분석기를 기준으로 정리합니다.
한글
Nori
:Elasticsearch/Opensearch의 공식 한글 형태소 분석기
Mecab
:오픈소스 한글(및 일본어) 형태소 분석기. Python, Java 등 바인딩 많음
Elastic/Opensearch 직접 연동은 제한적(플러그인 필요)
OpenKoreanText
(구 Twitter Korean Text):Java 기반 한글 분석, Spark 등에서 널리 사용
영어
Standard analyzer
(Elasticsearch 기본):- 토크나이저 + 불용어(stopwords) 처리 등 내장
Snowball
:- 어간 추출(stemming) 지원, 여러 언어 지원
Porter
:- 고전적인 어간 추출 알고리즘
일본어
Kuromoji
:Elasticsearch/Opensearch 공식 일본어 형태소 분석기
Mecab
:- 일본어 분석에 가장 널리 쓰임
범용
Standard analyzer
:- 영어 및 라틴계 언어에 적합
ICU analyzer
:다양한 언어 지원(Unicode 기반), Elastic 공식 플러그인
NLP 라이브러리
- Elasticsearch와 직접 연동은 아니지만, spaCy, NLTK, Stanza 등도 범용 형태소 분석 지원
2. 형태소 분석기 적용:
입력 데이터 vs 인덱스 매핑
요점
데이터를 입력할 때 미리 형태소 분석한 결과를 저장하는 게 아님!
인덱스를 만들 때(매핑 정의 시) “어떤 analyzer(형태소 분석기)”를 쓸지 필드별로 지정
이후
문서가 인덱싱(저장)될 때 자동으로 analyzer가 동작
쿼리할 때도 analyzer 지정 가능 (ex: 검색어도 같은 분석기로 쪼갬)
실제 예시
1. 인덱스 매핑 시 분석기 지정
1 | PUT /korean_docs |
- 이러면 content 필드는
입력할 때마다 Nori 형태소 분석기가 자동 적용
2. 쿼리 시 analyzer 지정
1 | GET /korean_docs/_search |
- 보통 인덱스 시에 지정한 분석기가 쿼리에도 자동 적용되므로 명시하지 않아도 됨
결론:
데이터를 사전에 형태소 분석해서 넣는 게 아니라,
인덱스 필드에 분석기를 지정하면 Elasticsearch/OpenSearch가 알아서 처리
특별한 경우(예: pre-tokenized field 등)만 미리 토큰화된 데이터를 입력할 때가 있음
3. 쿼리 최적화: RDBMS와의 차이점
RDBMS 쿼리 최적화
인덱스, 조인, 정규화/비정규화, 쿼리 플랜 등
이 중심일반적으로
정확한 값 기반 필터링
(where, join, group by 등)이 많음관계형 데이터
의 최적화(중복 최소화, 데이터 일관성)가 주 목적
Elasticsearch/OpenSearch 쿼리 최적화의 차이
주요 차이점
1. 스코어 기반 검색과 랭킹 중심
“정확하게 일치”보다 “얼마나 비슷한가”(relevance)가 더 중요함
쿼리 튜닝의 목표가
정확도와 속도의 균형
임
2. 역색인(inverted index) 기반 구조
대부분의 최적화는 “역색인 구조에 적합한 쿼리 작성”
불필요한 scoring을 피하고, filter 쿼리로 분리(필터는 빠름, 점수 없음)
3. 분산(샤드, 레플리카) 기반
데이터가 여러 서버로 나뉘어 저장됨
샤드 수, 레플리카 구성에 따라 성능 달라짐
4. Analyzer/Tokenizer 영향
쿼리 성능에 텍스트 분석기(형태소 분석, ngram, edge ngram 등)의 영향이 매우 큼
잘못된 analyzer 설정 → 인덱스 폭증/검색 속도 저하
5. Aggregation/집계 쿼리 최적화
- 집계(aggregation)는 RDB의 group by와 유사하나, 분산환경에서 성능 튜닝 필요
예시: 쿼리 최적화 팁
filter
와must
구분 사용 (filter는 scoring하지 않아 속도 빠름)source 필드 최소화
(_source: false 또는 필요한 필드만 요청)샤드/레플리카 튜닝
쿼리 프로파일링
(_search/profile 사용)Bulk indexing
(대량 인덱싱은 한번에)
참고
정리/요약
언어별 형태소 분석기
한글: Nori, Mecab, OpenKoreanText
영어: Standard, Snowball, Porter
일본어: Kuromoji, Mecab
범용: ICU, spaCy 등
형태소 분석기 지정:
입력 데이터 자체를 분석해서 저장하는 것이 아님
인덱스 매핑에서 analyzer 지정
→ Elasticsearch/OpenSearch가 자동 적용
쿼리 최적화의 차이:
RDBMS는 인덱스/정확매칭 중심
검색엔진은
역색인, 랭킹, 분산 구조, analyzer
영향이 크고, filter/must 구분, aggregation 튜닝 등이 중심
필요하면 각 주제별 더 깊은 예제/튜닝 방법도 제공 가능합니다!
궁금한 부분 있으면 더 구체적으로 질문 주세요.
참고:
Stopword 에 관해
https://github.com/apache/lucene/blob/main/lucene/analysis/common/src/resources/org/apache/lucene/analysis/cjk/stopwords.txt
기본적으로 한중일에 대해서 불용어 처리가 없다.
stop word(불용어) 처리기
는 검색엔진에서 “의미 없는 단어”(예: 영어의 “the”, “is”, “at” 또는 한국어의 “은”, “는”, “이”, “가” 등)를 인덱스와 쿼리에서 자동으로 제거
하여 검색 효율과 정확도를 높이는 데 사용합니다.
아래는 Elasticsearch / OpenSearch에서 stop word 처리기를 사용하는 방법
을 설명합니다.
1.
stop word의 기본 원리
인덱싱 시:
Analyzer가 텍스트를 토큰(단어)으로 분리할 때, stop word에 해당하는 단어는
자동으로 제거
됨 → 인덱스 크기 및 검색 속도 향상.검색(쿼리) 시:
입력 쿼리에서도 stop word가 제거되어, 실제로 검색에 의미 있는 단어만 남음.
2.
Elasticsearch/OpenSearch에서 stop word 적용 방법
A. 내장 analyzer 사용 (자동 적용)
영어의 경우:
standard, english analyzer 등은 기본적으로 stop word 처리가 내장되어 있음.
예시
1 | PUT /myindex |
- → english analyzer에는 불용어 리스트가 이미 포함되어 있음.
B. 커스텀 analyzer에서 stop word 처리기 지정
- 직접 원하는 불용어 리스트를 지정하거나, 내장 stop word filter를 명시적으로 추가할 수 있음.
예시 1: 영어 커스텀 불용어 처리기
1 | PUT /customstopindex |
예시 2: 한글 커스텀 불용어 처리기
- 한글은 내장 불용어 리스트가 제한적이므로 직접 지정하는 것이 일반적
1 | PUT /koreanindex |
3. 동작 확인 (예시)
분석 API로 동작 확인
1 | POST /koreanindex/_analyze |
→ 결과 토큰에서 “이”, “은” 등은 제거됨.
실제로 쿼리 시에도 동일하게 처리되어, “청바지” 같은 의미 있는 단어만 인덱싱/검색됨.
4.
참고자료
정리
stop word 처리기는 analyzer 설정에 filter로 추가
영어 등 일부 언어는 내장 stopword set 사용 가능
한글 등은 직접 리스트 지정 필요
인덱스 및 쿼리 양쪽 모두에서 stopword가 제거되어 의미 있는 검색 결과를 얻을 수 있음
- Nori 는 기본 설치, 은전한닢은 플러그인 설치 필요
기타 더 읽어본 것
https://helloworld.kurly.com/blog/2023-review-opensearch/ 컬리에서 opensearch 도입 후기
- 성능 테스트 : Ngrinder
https://danawalab.github.io/elastic/2023/01/05/MecabVsNori.html 다나와 기술 블로그 Nori, Mecab-Ko
- 사전 크기에 따라 인덱스 성능도 변화됨. 사전은 어떻게 유지관리 하는지가 문제가 될 수 있겠음
https://www.elastic.co/kr/blog/nori-the-official-elasticsearch-plugin-for-korean-language-analysis
우리나라 말은 합성어도 중요하기 때문에 decompound_mode 의 mixed 를 사용하는 것이 좋을 듯함.
https://velog.io/@window/Elasticsearch%ED%98%95%ED%83%9C%EC%86%8C-%EB%B6%84%EC%84%9D%EA%B8%B0 좀 더 자세한 nori 의 사용법. 한문->한자 등.
CJK analyzer (불용어도 포함) https://docs.opensearch.org/docs/latest/analyzers/language-analyzers/cjk/
LLM 도 쓴다고? 이건 나중에 https://docs.opensearch.org/docs/latest/ml-commons-plugin/pretrained-models/