Elasticsearch: 문자열 타입 (text vs keyword) 완벽 이해
Elasticsearch에서는 문자열 데이터를 저장할 때 text 타입과 keyword 타입을 사용할 수 있습니다.
✔ text: 검색을 위해 분석(Analyzed)되어 저장됨 (풀 텍스트 검색용)
✔ keyword: 분석 없이 원본 그대로 저장됨 (정확한 값 검색 및 정렬, 집계용)
이 글에서는 text와 keyword의 차이, 각각의 주요 옵션, 그리고 실전 적용 예제까지 상세히 알아보겠습니다.
1. Elasticsearch에서 문자열 데이터 저장 방식
🔹 문자열 데이터 저장 방식의 변화
Elasticsearch 2.x 이전에는 문자열(string) 타입만 존재했으며, 분석 여부를 옵션으로 구분했습니다.
하지만 5.0 이후부터는 text와 keyword 타입으로 나뉘면서, 텍스트 분석 여부를 명확히 구분하게 되었습니다.
2. text 타입 (검색용)
🔹 text란?
- 텍스트 분석기(Analyzer)를 적용하여 검색 최적화
- 문자열을 여러 개의 토큰(Token)으로 분리하여 역색인(Inverted Index) 저장
- 대용량 텍스트(본문, 설명, 제목 등)에 적합
- 집계(Aggregation)와 정렬(Sorting)에 비효율적 (메모리 사용량 증가)
📌 예제 1: text 필드 매핑
PUT my_index
{
"mappings": {
"properties": {
"title": {
"type": "text"
}
}
}
}
🔹 "The quick brown fox" → ["the", "quick", "brown", "fox"] 로 저장됨 ✅
🔹 text 필드의 주요 옵션
옵션 | 설명 | 기본값 |
analyzer | 색인 시 사용할 애널라이저 설정 | standard |
search_analyzer | 검색 시 사용할 애널라이저 설정 | 색인 애널라이저와 동일 |
index | 색인 여부 (검색 가능 여부) | true |
boost | 검색 시 가중치 부여 | 1 |
fielddata | 집계/정렬 가능 여부 (true 시 메모리 사용 증가) | false |
📌 예제 2: custom analyzer 적용
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"custom_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [ "lowercase", "stop" ]
}
}
}
},
"mappings": {
"properties": {
"description": {
"type": "text",
"analyzer": "custom_analyzer"
}
}
}
}
🔹 설명:
- "The QUICK brown fox" → ["quick", "brown", "fox"] 로 저장됨 (대소문자 변환, 불용어 제거)
3. keyword 타입 (정확한 값 검색 및 정렬)
🔹 keyword란?
- 분석되지 않고 원본 그대로 저장
- 정확한 값 비교(Exact Matching), 필터링, 정렬, 집계에 최적화
- 소문자 변환, 불용어 제거 등의 처리가 필요 없다면 사용
- 검색에는 부적합하지만, 집계(Aggregation)에는 필수
📌 예제 3: keyword 필드 매핑
PUT my_index
{
"mappings": {
"properties": {
"category": {
"type": "keyword"
}
}
}
}
🔹 "The quick brown fox" → ["The quick brown fox"] 그대로 저장 ✅
🔹 keyword 필드의 주요 옵션
옵션 | 설명 | 기본값 |
doc_values | 집계/정렬 시 메모리 사용 최적화 | true |
ignore_above | 특정 길이 이상 문자열 색인 제외 | 256 (동적 매핑 시) |
normalizer | 대소문자 변환 등 기본적인 문자 변환 가능 | 없음 |
📌 예제 4: normalizer 적용 (소문자 변환)
PUT my_index
{
"settings": {
"analysis": {
"normalizer": {
"custom_normalizer": {
"type": "custom",
"filter": ["lowercase"]
}
}
}
},
"mappings": {
"properties": {
"tag": {
"type": "keyword",
"normalizer": "custom_normalizer"
}
}
}
}
🔹 "Elasticsearch" → "elasticsearch" 로 변환 후 저장 ✅
4. text vs keyword 비교
비교 항목 | text | keyword |
저장 방식 | 분석(Analyzed) 후 토큰화됨 | 원본 그대로 저장 |
검색 방식 | 풀 텍스트 검색 (Match Query) | 정확한 값 검색 (Term Query) |
정렬(Sorting) | ❌ 불가능 (fielddata 필요) | ✅ 가능 |
집계(Aggregation) | ❌ 비효율적 | ✅ 최적 |
필터(Filter) | ❌ 비효율적 | ✅ 최적 |
애널라이저 사용 | ✅ 가능 | ❌ 불가능 (normalizer 사용 가능) |
📌 keyword 필드의 Term Query 예제
GET my_index/_search
{
"query": {
"term": {
"category": "Elasticsearch"
}
}
}
✅ "Elasticsearch"와 정확히 일치하는 문서만 검색
📌 text 필드의 Match Query 예제
GET my_index/_search
{
"query": {
"match": {
"title": "Elasticsearch Guide"
}
}
}
✅ "Elasticsearch"와 "Guide"가 포함된 문서 검색
5. text와 keyword 함께 사용하기 (Multi-Field)
Elasticsearch에서는 text와 keyword를 동시에 사용할 수 있습니다.
✔ 검색 시 text 필드 사용
✔ 필터링, 정렬, 집계 시 keyword 필드 사용
📌 예제 5: Multi-Field 설정
PUT my_index
{
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
🔹 검색: title 필드 사용
🔹 정렬/집계: title.keyword 필드 사용
📌 Match Query (검색)
GET my_index/_search
{
"query": {
"match": {
"title": "Elasticsearch Guide"
}
}
}
✅ "Elasticsearch Guide" 관련 문서 검색
📌 Term Query (정확한 값 검색)
GET my_index/_search
{
"query": {
"term": {
"title.keyword": "Elasticsearch Guide"
}
}
}
✅ "Elasticsearch Guide"와 정확히 일치하는 문서 검색
6. 정리
개념 | 설명 |
text 타입 | 분석(Analyzed)되어 검색 최적화, 집계/정렬 비효율적 |
keyword 타입 | 원본 그대로 저장, 필터링/정렬/집계 최적화 |
text 필드 옵션 | analyzer, search_analyzer, boost, fielddata |
keyword 필드 옵션 | doc_values, ignore_above, normalizer |
Multi-Field 사용 | 검색(text) + 집계/정렬(keyword) 함께 사용 |
7. 학습 가이드
1️⃣ text와 keyword 차이를 실습하며 비교
2️⃣ Analyzer와 Normalizer를 적용하여 다양한 문자열 처리 연습
3️⃣ Multi-Field 설정하여 검색 및 정렬 최적화
4️⃣ keyword 필드를 활용한 Term Query & Aggregation 실습
다음 학습에서는 Analyzer와 Tokenizer를 활용한 텍스트 분석 심화 과정을 다루겠습니다! 🚀
'Elastic Search > 인덱스 설정과 매핑' 카테고리의 다른 글
[Mappings] Boolean(불리언) 타입 완벽 정리 (0) | 2025.02.03 |
---|---|
[Mappings] 날짜(Date) 타입 완벽 정리 (0) | 2025.02.03 |
[Mappings] 숫자 데이터 타입 (long, double, scaled_float 등) (0) | 2025.02.03 |
[Elasticsearch] 매핑(Mappings) (0) | 2025.02.03 |
[Elasticsearch] 설정(Settings) 이해하기 (0) | 2025.02.03 |