1. ElasticSearch 개요 및 아키텍처
1.1 ElasticSearch란?
- 오픈소스 기반의 분산형 검색 및 분석 엔진입니다.
- JSON 기반 RESTful API를 제공하여 다양한 애플리케이션과 쉽게 연동 가능합니다.
- Apache Lucene을 기반으로 개발된 고성능 검색 엔진입니다.
- Apache Lucene은 고성능, 확장 가능한 오픈소스 검색 라이브러리로, Java 기반으로 개발되었습니다.
- 검색 엔진의 핵심 기능을 제공하며, 텍스트 기반의 색인(Indexing) 및 검색(Search) 기능을 수행합니다.
- Lucene은 독립적인 검색 라이브러리이지만, ElasticSearch, Solr 같은 검색 엔진의 핵심 컴포넌트로 사용됩니다.
- ElasticSearch는 Lucene을 기반으로 구축되었으며, Lucene의 강력한 검색 기능을 RESTful API로 제공하는 구조입니다.
1.1.1 Apache Lucene의 주요 특징
- 텍스트 색인 및 검색
- Lucene은 문서를 토큰화(Tokenization) 하고, 역색인(Inverted Index) 구조를 생성하여 빠른 검색이 가능하도록 합니다.
- 강력한 검색 기능
- Full-Text Search (단어, 문장, 구문 검색)
- Full-Text Search(전문 검색)는 문서나 데이터에서 텍스트 기반으로 원하는 정보를 빠르게 검색하는 방법입니다.
- 단순한 문자열 검색이 아니라, 자연어 처리 기법을 적용하여 보다 정확한 검색 결과를 제공합니다.
- Full-Text Search의 특징
-
단순한 문자열 검색과 차별화됨
- 일반적인
LIKE 검색(SQL WHERE name LIKE '%keyword%')은 해당 문자열이 포함된 레코드를 검색하지만, Full-Text Search는 의미적으로 관련 있는 단어까지 검색 가능합니다.
-
역색인(Inverted Index) 방식 사용
- 문서 전체를 검색하는 것이 아니라, 단어 단위로 인덱스를 생성하여 빠르게 검색할 수 있습니다.
- 기존 색인 방식(Sequential Search): 문서를 처음부터 끝까지 순차적으로 탐색 → 속도가 느림
- 역색인 방식: 단어를 기준으로 인덱스를 생성하고, 해당 단어가 포함된 문서를 매핑 → 검색 속도 향상
- 예) 문서 데이터
| 문서 ID | 내용 |
|---|
| 1 | "Elasticsearch is a search engine" |
| 2 | "A search engine is powerful" |
| 단어 | 포함된 문서 ID |
|---|
Elasticsearch | 1 |
search | 1, 2 |
engine | 1, 2 |
powerful | 2 |
- 이와 같이 문서 1과 2에서 해당 단어를 포함하는 문서를 빠르게 찾을 수 있습니다.
-
토큰화(Tokenization) 및 텍스트 분석
- 문장을 단어(Token) 단위로 분리하고, 불필요한 단어(Stop Words)를 제거하며, 동의어 및 어근(Stem) 처리를 수행합니다.
- 예)
"Elasticsearch is a distributed search engine"
- 토큰화 결과
- →
["elasticsearch", "distributed", "search", "engine"]
- (불필요한 단어
is, a 제거됨)
- 어근 분석(Stemming)
- 동일한 의미의 단어를 하나로 통합하여 검색 성능을 향상시키는 기법입니다
- 예)
-
"running", "runner", "runs" → "run"
-
"better", "best" → "good"
ElasticSearch에서는 Stemmer Analyzer를 사용하여 이를 처리할 수 있습니다.
-
Ranking(가중치 부여) 및 검색 결과 정렬
- 검색어와 문서 간의 관련성(검색 점수, TF-IDF, BM25)을 기반으로 검색 결과 정렬이 가능합니다.
- TF-IDF: 특정 단어가 문서에서 얼마나 중요한지를 평가하는 알고리즘
- BM25: TF-IDF를 개선한 알고리즘으로, 문서 길이에 따라 가중치를 조정하여 검색 결과의 품질을 향상시킴
- Boolean Query (
AND, OR, NOT 연산자 지원)
- Boolean Query(부울 쿼리)는 여러 개의 검색 조건을 조합하여 더욱 정교한 검색을 수행할 수 있도록 하는 ElasticSearch의 기능입니다.
- SQL에서
AND, OR, NOT 연산자를 사용하여 데이터를 필터링하는 것과 유사합니다.
- 주요 특징
-
다양한 검색 조건을 조합하여 정확한 검색 결과 제공
-
복합적인 검색 로직 구현 가능
-
AND, OR, NOT과 같은 논리 연산을 활용하여 필터링 수행
| 조건 키워드 | 역할 |
|---|
must | 모든 조건을 만족해야 검색 결과 포함 (AND 연산) |
should | 하나 이상의 조건을 만족하면 포함 (OR 연산) |
must_not | 이 조건에 해당하는 문서를 제외 (NOT 연산) |
filter | 검색 성능 최적화를 위한 필터 적용 (캐싱 가능) |
- Wildcard 검색 (
?, *``와일드카드 사용 가능)
- Wildcard 검색은 특정 패턴에 일치하는 단어를 검색하는 방법으로, ElasticSearch에서 부분 일치 검색(Partial Match)을 수행할 때 사용됩니다. SQL의
LIKE '%keyword%'와 유사하지만, ElasticSearch에서는 역색인(Inverted Index) 을 활용하여 훨씬 더 빠르고 효율적인 검색을 제공합니다.
- 주의
- Wildcard 검색은 검색 성능에 영향을 줄 수 있으므로, 지나치게 광범위한 패턴을 사용하는 것은 권장되지 않습니다.
- 주요 특징
- 특정 패턴을 포함하는 단어 검색 가능
- SQL의
LIKE 검색보다 성능이 뛰어남
* 와 ? 와일드카드 사용 가능
- ElasticSearch는 기본적으로 대소문자를 구분
- 대소문자를 구분하지 않으려면
lowercase 필터 필요
| 와일드카드 기호 | 설명 | 예제 | 검색 결과 |
|---|
* | 0개 이상의 문자와 일치 | te* | test, team, text |
? | 단일 문자 하나와 일치 | te?t | test, text (but not teet) |
| | | |
- Proximity 검색 (두 단어 사이의 거리를 고려한 검색)
- Proximity 검색(근접 검색)은 검색어 간의 거리를 고려하여 검색 결과를 반환하는 방식입니다.
- 즉, 두 개 이상의 단어가 특정 거리 내에 존재하는 경우에만 검색 결과를 반환합니다.
- 일반적인 Full-Text 검색과 다르게, 단어 간의 위치를 고려한 검색을 수행합니다.
- Proximity 검색이 필요한 이유
- 유연한 검색 가능
- 단순한 키워드 검색보다 단어 간의 관계를 고려하여 검색 정확도 향상
- 예:
"quick brown fox" 과 "brown quick fox" 를 같은 의미로 검색
- 문서 내 단어 순서가 다른 경우에도 검색 가능
"fast car" → "car fast" 도 검색 가능
- 일정 거리 내에서만 단어가 함께 나타날 경우 검색
"Artificial Intelligence" 와 "Intelligence Artificial"을 검색할 때 단어 간 거리를 제한 가능
- Ranking (TF-IDF, BM25) (검색 결과의 중요도 평가)
- Ranking(랭킹)은 검색 결과에서 문서의 중요도(Relevance Score)를 평가하여, 사용자가 원하는 정보를 우선적으로 제공하는 기능입니다.
- ElasticSearch는 TF-IDF(Term Frequency - Inverse Document Frequency) 및 BM25(Best Matching 25) 알고리즘을 사용하여 검색 결과의 순위를 정합니다.
- TF-IDF는 문서 내에서 단어의 중요도를 계산하는 대표적인 검색 알고리즘입니다.

- **TF(Term Frequency, 단어 빈도수)**TF = 문서 내 전체 단어 개수특정 단어가 해당 문서에 등장한 횟수
- 특정 문서에서 특정 단어가 등장하는 횟수
- 문서 내에서 자주 등장할수록 중요도가 높아짐
- 하지만, 모든 문서에서 많이 등장하는 단어(예: "the", "is")는 중요도가 낮아야 함

- **IDF(Inverse Document Frequency, 역문서 빈도수)**IDF=log(해당 단어를 포함한 문서 수+1전체 문서 수)
- 특정 단어가 전체 문서에서 얼마나 희귀한지를 계산
- 흔한 단어는 점수를 낮추고, 특정 문서에서만 자주 나오는 단어는 점수를 높임

- * 역색인(Inverted Index) 방식 사용
- Lucene은 역색인(Inverted Index) 방식을 사용하여 검색 속도를 최적화합니다.
- 일반적인 데이터베이스는 순차적 검색(Sequential Search) 을 사용하지만, Lucene은 역색인을 활용하여 빠르게 검색할 수 있습니다.
- 역색인은 단어와 해당 단어가 포함된 문서 ID 목록을 매핑하는 데이터 구조입니다.
- 유연한 문서 구조
- Lucene은 문서(Document) 기반 저장 방식을 사용하며, 각 문서는 필드(Field)로 구성됨
- 필드는 여러 유형(String, Integer, Date 등)을 지원
- 확장 가능성
- 대량의 데이터를 효율적으로 색인 가능
- 멀티스레딩 지원, 빠른 검색 속도 유지
1.2 ElasticSearch 활용 사례
- 로그 및 모니터링 데이터 분석 (ELK Stack)
- 웹사이트 검색 시스템 (전자상거래, 문서 검색 등)
- 빅데이터 분석 및 머신러닝 기반 데이터 처리
1.3 ElasticSearch의 주요 기능
- 강력한 Full-Text 검색 지원
- 분산 아키텍처를 통한 수평 확장 지원
- 다양한 쿼리 언어(Query DSL) 및 집계(Aggregation) 기능 제공
- 실시간 데이터 색인 및 분석 가능
1.4 ElasticSearch 아키텍처

https://devopsideas.com/different-elasticsearch-components-and-what-they-mean-in-5-mins/
- Cluster
- 여러 개의 노드로 구성된 ElasticSearch의 전체 시스템
- Node
- 클러스터 내에서 데이터를 저장하고 검색 요청을 처리하는 개별 서버
- Index
- 클러스터 내부에서 노드는 다음과 같은 역할을 합니다.
- Master Node
- Data Node
- Ingest Node
- Coordinator Node
- Shard와 Replica
- 샤드 → 데이터를 분할하여 저장하는 기본 단위
- 레플리카 → 데이터 복제본을 유지하여 고가용성 제공
- 샤드와 레플리카 개수 조절을 통해 ElasticSearch의 성능 최적화가 가능합니다.
1.5 클러스터 상태
- 엘라스틱서치에서 클러스터 상태는 세 가지 색상, 즉 green, yellow, red로 표시됩니다.
- 각 색상은 클러스터의 건강 상태를 나타내며, 다음과 같은 의미를 가집니다.
- Green (녹색)
- 클러스터의 모든 주 샤드(primary shards)와 복제 샤드(replica shards)가 정상적으로 할당되어 있습니다.
- 이 상태는 클러스터가 최적의 상태에 있으며 모든 데이터가 안전하게 복제된 것을 의미합니다.
- Yellow (노란색)
- 모든 주 샤드는 할당되었으나 하나 이상의 복제 샤드가 할당되지 않았습니다.
- 주 샤드는 사용 가능하지만, 일부 복제 샤드가 할당되지 않아 데이터의 내고장성이 완벽하지 않은 상태입니다.
- 주 샤드의 노드가 실패할 경우, 해당 데이터의 복제본이 없어 데이터 손실의 가능성이 있습니다.
- Red (적색)
- 하나 이상의 주 샤드가 할당되지 않은 상태입니다.
- 데이터의 일부가 사용 불가능함을 의미하며, 시스템에 문제가 있는 상태입니다.
- 적색 상태에서는 해당 샤드의 데이터에 접근할 수 없으므로 데이터 손실이 발생할 수 있습니다.
- 클러스터의 상태는 주 샤드와 복제 샤드의 할당 여부에 따라 결정되며, 데이터의 가용성과 안정성을 직접적으로 반영합니다.

1.6 공식 문서

2. ElasticSearch 구축
2.1 Docker-Compose 파일 작성
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.5.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
volumes:
- esdata:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:8.5.0
container_name: kibana
ports:
- "5601:5601"
depends_on:
- elasticsearch
volumes:
esdata:
driver: local
2.2 ElasticSearch 및 Kibana 실행
docker-compose up -d
2.3 ElasticSearch 상태 확인
curl -X GET "http://localhost:9200/_cluster/health?pretty"
3. 데이터 인덱싱 및 검색 실습
3.1 샘플 데이터 인덱스 생성
curl -X PUT "http://localhost:9200/sample_index" -H 'Content-Type: application/json' -d'
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"name": { "type": "text" },
"age": { "type": "integer" },
"city": { "type": "keyword" }
}
}
}'
3.2 데이터 삽입
curl -X POST "http://localhost:9200/sample_index/_doc/1" -H 'Content-Type: application/json' -d'
{
"name": "Sam Doe",
"age": 40,
"city": "Seoul"
}'
3.3 데이터 검색 (Query DSL 활용)
curl -X GET "http://localhost:9200/sample_index/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"name": "John"
}
}
}'