Elasticsearch: 멀티 필드 (Multi Field) 완벽 정리

Elasticsearch에서는 하나의 필드에 여러 개의 분석 방식(Analyzer) 또는 타입을 적용할 수 있습니다.
하나의 필드 값을 여러 개의 역색인 방식으로 저장 가능
Text 필드에 Keyword 타입을 추가하여 검색 & 정렬 가능
다국어 문서 분석을 위해 여러 개의 애널라이저 적용 가능

이번 글에서는 멀티 필드(Multi Field)의 개념, 설정 방법, 활용 예제, 그리고 실전 적용 방법까지 상세히 알아보겠습니다.


1. 멀티 필드 개요

특징 설명 활용 사례
하나의 필드에 여러 타입 저장 text, keyword 타입을 함께 저장 가능 검색 & 정렬 모두 필요할 때
여러 개의 애널라이저 적용 가능 동일한 필드를 다른 방식으로 분석 가능 다국어 검색 최적화
동일한 데이터를 다양한 방법으로 색인 필드명 + . 을 추가하여 관리 message.english, message.nori

2. 멀티 필드 설정

🔹 멀티 필드 기본 개념

✔ fields 옵션을 사용하여 하나의 필드를 여러 개의 서브 필드로 확장
✔ text 타입은 검색용으로 사용하고, keyword 타입은 정렬/집계용으로 활용

📌 예제 1: text + keyword 타입의 멀티 필드 설정

PUT my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

title 필드는 text 타입이지만 title.keyword는 keyword 타입으로 저장됨

📌 예제 2: 데이터 저장

PUT my_index/_doc/1
{
  "title": "Elasticsearch Multi Field Test"
}

이제 title 필드는 title.keyword 서브 필드와 함께 저장됨

📌 예제 3: title 필드 검색 (text 타입)

GET my_index/_search
{
  "query": {
    "match": {
      "title": "Elasticsearch"
    }
  }
}

text 타입이므로 형태소 분석 후 검색 가능

📌 예제 4: title.keyword 필드 검색 (keyword 타입)

GET my_index/_search
{
  "query": {
    "term": {
      "title.keyword": "Elasticsearch Multi Field Test"
    }
  }
}

keyword 타입이므로 정확한 문자열 검색만 가능

📌 예제 5: keyword 타입으로 정렬하기

GET my_index/_search
{
  "sort": [
    { "title.keyword": "asc" }
  ]
}

정확한 문자열 기준으로 정렬 가능


3. 멀티 필드에서 애널라이저(Analyzer) 적용

🔹 멀티 필드를 활용한 다국어 검색

✔ text 타입 필드에 여러 개의 애널라이저를 적용할 수 있음
한국어, 영어, 일본어 등 다국어 지원에 유용

📌 예제 6: english, nori(한국어) 애널라이저를 적용한 멀티 필드 설정

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "nori_analyzer": {
          "tokenizer": "nori_tokenizer"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "message": {
        "type": "text",
        "fields": {
          "english": {
            "type": "text",
            "analyzer": "english"
          },
          "nori": {
            "type": "text",
            "analyzer": "nori_analyzer"
          }
        }
      }
    }
  }
}

message.english → 영어 전용 애널라이저 적용
message.nori → 한국어 전용 애널라이저 적용

📌 예제 7: 데이터 저장

PUT my_index/_doc/1
{
  "message": "My favorite 슈퍼영웅 is Iron Man"
}

Elasticsearch는 message, message.english, message.nori 필드로 각각 색인

📌 예제 8: message 필드에서 "영웅" 검색 (text 타입)

GET my_index/_search
{
  "query": {
    "match": {
      "message": "영웅"
    }
  }
}

기본 message 필드에서는 검색되지 않음

📌 예제 9: message.nori 필드에서 "영웅" 검색 (한국어 애널라이저 적용)

GET my_index/_search
{
  "query": {
    "match": {
      "message.nori": "영웅"
    }
  }
}

한국어 애널라이저를 적용한 message.nori 필드에서는 정상적으로 검색됨


4. 정리

     
멀티 필드란? 하나의 필드를 여러 개의 타입/애널라이저로 저장하는 방식 fields 옵션 사용
주요 활용 예시 text + keyword 조합으로 검색 & 정렬 지원 title.keyword
다국어 검색 지원 같은 데이터를 여러 애널라이저로 색인 message.english, message.nori
정확한 검색 keyword 타입을 활용하여 정확한 문자열 검색 가능 "match": { "title.keyword": "..." }
검색 최적화 text 필드는 전체 검색, keyword 필드는 필터링 & 정렬 검색 속도 개선 가능

5. 학습 가이드

1️⃣ 멀티 필드를 활용하여 text + keyword 조합을 테스트
2️⃣ 여러 애널라이저(english, nori)를 적용하여 다국어 검색 실습
3️⃣ 정확한 검색(Keyword)과 유사 검색(Text)의 차이를 비교


6. 마무리

Elasticsearch의 멀티 필드(Multi Field) 기능을 활용하면
동일한 데이터를 여러 방식으로 색인할 수 있으며
검색 최적화(정렬 & 집계)다국어 분석에도 매우 유용합니다.

다음 학습에서는 멀티 필드를 활용한 고급 검색 최적화 및 성능 개선 전략을 다루겠습니다! 🚀

Elasticsearch: 기타 필드 타입 (IP, Range, Binary) 완벽 정리

Elasticsearch는 기본적인 문자열, 숫자, 날짜, 불리언, 위치 정보 외에도
IP 주소 저장 (ip 타입)
범위 데이터 저장 (range 타입)
바이너리 데이터 저장 (binary 타입)

을 지원합니다. 이번 글에서는 각 필드 타입의 특성, 매핑 설정, 검색 방식, 그리고 실전 활용 예제까지 상세히 알아보겠습니다.


1. 기타 필드 타입 개요

타입 특징 사용 예시
IP (ip) IPv4, IPv6 주소 저장 "192.168.1.1"
Range (range) 숫자, 날짜, IP 범위 저장 { "gte": 10, "lt": 20 }
Binary (binary) 바이너리 데이터 저장 (검색 불가능) "U29tZSBiaW5hcnkgZGF0YQ=="

2. IP (ip) 타입

🔹 IP 타입이란?

IPv4 및 IPv6 주소를 저장할 수 있는 데이터 타입
쿼리를 활용해 특정 IP 대역 검색 가능

📌 예제 1: IP 필드 매핑 설정

PUT my_ip_index
{
  "mappings": {
    "properties": {
      "client_ip": {
        "type": "ip"
      }
    }
  }
}

IPv4, IPv6 주소를 문자열처럼 저장 가능

📌 예제 2: IP 데이터 저장

PUT my_ip_index/_doc/1
{
  "client_ip": "192.168.1.1"
}
PUT my_ip_index/_doc/2
{
  "client_ip": "2001:db8::ff00:42:8329"
}

IPv4, IPv6 모두 저장 가능

📌 예제 3: 특정 IP 검색

GET my_ip_index/_search
{
  "query": {
    "term": {
      "client_ip": "192.168.1.1"
    }
  }
}

특정 IP 주소를 기준으로 검색 가능

📌 예제 4: 특정 IP 범위 검색 (range 쿼리)

GET my_ip_index/_search
{
  "query": {
    "range": {
      "client_ip": {
        "gte": "192.168.1.0",
        "lte": "192.168.1.255"
      }
    }
  }
}

지정된 IP 범위 내에 포함된 데이터 검색 가능


3. 범위 (range) 타입

🔹 Range 타입이란?

숫자, 날짜, IP 등의 범위를 저장할 수 있는 데이터 타입
쿼리를 활용해 특정 범위의 데이터를 검색 가능

📌 예제 5: Range 필드 매핑 설정

PUT my_range
{
  "mappings": {
    "properties": {
      "amount": {
        "type": "integer_range"
      },
      "days": {
        "type": "date_range"
      }
    }
  }
}

정수 범위(integer_range), 날짜 범위(date_range) 모두 저장 가능

📌 예제 6: Range 데이터 저장

PUT my_range/_doc/1
{
  "amount": {
    "gte": 19,
    "lt": 28
  },
  "days": {
    "gt": "2019-06-01T09:00:00",
    "lt": "2019-06-20"
  }
}

gte, gt, lte, lt 연산자를 사용하여 범위 지정 가능

📌 예제 7: 특정 범위 검색 (range 쿼리)

GET my_range/_search
{
  "query": {
    "range": {
      "amount": {
        "gte": 16,
        "lte": 25,
        "relation": "intersects"
      }
    }
  }
}

16~25 범위에 겹치는(intersects) 데이터를 검색 가능

📌 Range 쿼리의 relation 옵션

값 설명

   
within 도큐먼트의 범위가 쿼리 범위 안에 완전히 포함되는 경우
contains 쿼리 범위가 도큐먼트 범위 안에 완전히 포함되는 경우
intersects 도큐먼트 범위와 쿼리 범위가 겹치는 경우

📌 예제 8: 특정 날짜 범위 검색

GET my_range/_search
{
  "query": {
    "range": {
      "days": {
        "gte": "2019-06-05",
        "lte": "2019-06-15",
        "relation": "within"
      }
    }
  }
}

2019-06-05 ~ 2019-06-15 범위에 완전히 포함된 데이터 검색


4. 바이너리 (binary) 타입

🔹 Binary 타입이란?

파일, 이미지 등의 바이너리 데이터를 저장 가능
색인이 불가능하며, source에서만 조회 가능
보통 Elasticsearch에 직접 저장하기보다는 S3, HDFS 등 외부 저장소 활용 추천

📌 예제 9: Binary 필드 매핑 설정

PUT my_binary_index
{
  "mappings": {
    "properties": {
      "file_data": {
        "type": "binary"
      }
    }
  }
}

바이너리 데이터는 검색 및 집계 불가능 (색인 X)

📌 예제 10: 바이너리 데이터 저장

PUT my_binary_index/_doc/1
{
  "file_data": "U29tZSBiaW5hcnkgZGF0YQ=="
}

Base64 인코딩된 바이너리 데이터 저장 가능

📌 Binary 데이터는 가능하면 외부 저장소에 저장하고, Elasticsearch에는 URL 또는 키만 저장하는 것이 효율적


5. 정리

     
IP (ip) IPv4, IPv6 주소 저장 가능 "192.168.1.1"
IP 검색 (range) 특정 IP 범위 검색 가능 192.168.1.0 ~ 192.168.1.255
Range (range) 숫자, 날짜, IP 범위 저장 가능 { "gte": 10, "lt": 20 }
Range 검색 (relation) within, contains, intersects 옵션 활용 "relation": "intersects"
Binary (binary) 바이너리 데이터 저장 가능 (검색 불가) "U29tZSBiaW5hcnkgZGF0YQ=="

6. 학습 가이드

1️⃣ IP 주소(ip 타입) 데이터를 저장하고 특정 IP 범위 검색 실습
2️⃣ Range 데이터(range 타입)에서 within, contains, intersects 차이 이해
3️⃣ Binary 데이터(binary 타입)를 활용한 효율적인 데이터 저장 전략 고민


7. 마무리

Elasticsearch는 IP, 범위 데이터, 바이너리 데이터까지 다양한 데이터 타입을 지원하며
IP 데이터 검색 (특정 IP 및 범위 검색)
Range 데이터 활용 (숫자·날짜·IP 범위 저장 및 검색)
Binary 데이터 관리 (외부 저장소 연동 추천)

을 효과적으로 활용할 수 있습니다.

다음 학습에서는 Elasticsearch에서 필드 타입 최적화 및 성능 개선 방법을 다루겠습니다! 🚀

Elasticsearch: 위치 정보 (Geo Point & Geo Shape) 완벽 정리

Elasticsearch는 위치 정보(Geo Data)를 저장하고 검색할 수 있도록
Geo Point (한 점의 위도·경도 좌표)
Geo Shape (점, 선, 다각형 등 복잡한 형태)
위치 기반 검색 (거리, 범위, 포함 관계)

을 지원합니다. 이번 글에서는 위치 정보의 저장 방식, 검색 방식, 그리고 실전 활용 예제까지 상세히 알아보겠습니다.


1. Elasticsearch에서 지원하는 위치 정보 타입

타입 특징 사용 예시
Geo Point 위도(latitude), 경도(longitude) 좌표를 저장 특정 좌표에서 가까운 위치 검색
Geo Shape 다각형, 선, 여러 개의 점 등 복잡한 형태 저장 가능 행정 구역, 도로망, 특정 지역 검색

2. Geo Point

🔹 Geo Point란?

✔ 하나의 점(위도·경도)을 저장하는 데이터 타입
다양한 형식으로 좌표 입력 가능

📌 예제 1: Geo Point 필드 매핑 설정

PUT my_locations
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}

Geo Point 필드는 반드시 사전 매핑 설정 필요!

📌 예제 2: 다양한 형식으로 좌표 입력하기

PUT my_locations/_doc/1
{
  "location": { "lat": 41.12, "lon": -71.34 }  // 객체 형식
}
PUT my_locations/_doc/2
{
  "location": "41.12,-71.34"  // 문자열 형식
}
PUT my_locations/_doc/3
{
  "location": [ -71.34, 41.12 ]  // 배열 형식 (경도, 위도 순서)
}
PUT my_locations/_doc/4
{
  "location": "drm3btev3e86"  // geohash 형식
}

객체, 문자열, 배열, geohash 등 다양한 형식 지원
배열 형식은 "경도(lon) → 위도(lat)" 순서 주의!


3. Geo Point 검색 (Bounding Box & Distance)

🔹 Bounding Box 쿼리 (네모 영역 검색)

위쪽 좌표(top_left)와 아래쪽 좌표(bottom_right)로 범위 지정
네모 범위 내에 포함된 모든 위치 검색

📌 예제 3: 특정 영역 내에 위치한 점 찾기

GET my_locations/_search
{
  "query": {
    "geo_bounding_box": {
      "location": {
        "top_left": { "lat": 37.5779, "lon": 126.9617 },
        "bottom_right": { "lat": 37.4899, "lon": 127.0388 }
      }
    }
  }
}

지정된 네모 영역 내에 위치한 좌표 검색 가능


🔹 Distance 쿼리 (반경 검색)

하나의 기준점에서 일정 거리 내에 있는 좌표 검색
"반경 5km 안에 있는 위치" 같은 검색에 사용

📌 예제 4: 반경 5km 내에 위치한 점 찾기

GET my_locations/_search
{
  "query": {
    "geo_distance": {
      "distance": "5km",
      "location": { "lat": 37.5358, "lon": 126.9559 }
    }
  }
}

반경 5km 안에 포함된 모든 위치 검색 가능
distance 값을 10km, 20km로 변경하여 범위 조절 가능


4. Geo Shape

 

 

🔹 Geo Shape이란?

다각형, 선, 직사각형 등 복잡한 위치 정보 저장 가능
행정 구역, 특정 지역 검색에 활용

📌 예제 5: Geo Shape 필드 매핑 설정

PUT my_shapes
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_shape"
      }
    }
  }
}

Geo Shape은 점(Point)뿐만 아니라 선(Line), 다각형(Polygon)도 저장 가능

📌 예제 6: 다양한 Geo Shape 데이터 저장

PUT my_shapes/_doc/1
{
  "location": {
    "type": "point",
    "coordinates": [127.027926, 37.497175]
  }
}
PUT my_shapes/_doc/2
{
  "location": {
    "type": "polygon",
    "coordinates": [
      [
        [127.027926, 37.497175],
        [126.991806, 37.571607],
        [126.924191, 37.521624],
        [127.027926, 37.497175]  // 시작점과 동일해야 함
      ]
    ]
  }
}

다각형은 반드시 첫 번째 좌표와 마지막 좌표가 동일해야 함


5. Geo Shape 검색 (Intersects, Within, Disjoint)

Geo Shape을 이용한 복잡한 위치 검색 가능
관계(Relation) 옵션을 사용하여 다양한 검색 가능

Relation 값 설명

   
intersects 쿼리 영역과 조금이라도 겹치는 도큐먼트 검색
within 쿼리 영역에 완전히 포함되는 도큐먼트 검색
disjoint 쿼리 영역과 겹치지 않는 도큐먼트 검색

📌 예제 7: 특정 영역과 겹치는 위치 찾기 (intersects)

GET my_shapes/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "shape": {
          "type": "envelope",
          "coordinates": [
            [126.9687, 37.58], 
            [126.99, 37.5543]
          ]
        },
        "relation": "intersects"
      }
    }
  }
}

지정된 영역과 겹치는 도큐먼트 검색 가능


6. Object vs Geo Point vs Geo Shape 비교

     
Object JSON 객체 내부에 lat, lon 필드 저장 일반 텍스트 필드처럼 다룸
Geo Point 위도·경도를 한 점으로 저장 거리 기반 검색 가능 (geo_distance)
Geo Shape 다각형, 선, 다중 점 등 복잡한 형태 저장 특정 영역 검색 (geo_shape)

7. 정리

     
Geo Point 하나의 위도·경도를 저장 "서울역에서 반경 5km 내" 검색
Geo Shape 다각형, 선, 직사각형 등 복잡한 형태 저장 "강남구에 포함된 장소" 검색
Bounding Box Query 네모 영역 내 좌표 검색 "서울 시내에 포함된 역 찾기"
Distance Query 반경 내 좌표 검색 "5km 이내에 있는 카페 검색"
Geo Shape Query 특정 지역과 겹치는 도큐먼트 검색 "서울시 안에 완전히 포함된 도로 찾기"

8. 학습 가이드

1️⃣ Geo Point와 Geo Shape 데이터를 각각 저장하여 테스트
2️⃣ Bounding Box & Distance Query를 사용하여 위치 검색 실습
3️⃣ Geo Shape Query를 활용하여 특정 지역 검색 테스트


9. 마무리

Elasticsearch의 위치 정보(Geo Data) 기능을 활용하면
위치 기반 검색 (반경 내 검색, 특정 지역 검색 등)
복잡한 지도 데이터 처리 (도로망, 행정 구역 등)
다양한 위치 필터링 및 최적화된 공간 검색

을 쉽게 구현할 수 있습니다.

다음 학습에서는 Geo Query 성능 최적화 및 실전 활용법을 다루겠습니다! 🚀

Elasticsearch: Object vs Nested 타입 완벽 정리

Elasticsearch에서 Object와 Nested 타입JSON 객체(Object) 데이터를 저장하고 검색하는 방식을 결정하는 중요한 개념입니다.

Object 타입: 객체 내부의 필드들을 독립적으로 색인
Nested 타입: 객체 내부의 필드들을 하나의 단위로 유지하며 별도 저장

이번 글에서는 Object와 Nested 타입의 차이, 각 타입의 데이터 저장 방식, 검색 방식, 그리고 실전 예제까지 상세히 알아보겠습니다.


1. Object와 Nested의 차이점

타입 특징 검색 방식
Object JSON 객체를 필드별로 분리하여 색인 일반 Match Query 사용
Nested JSON 객체를 독립된 문서처럼 저장 Nested Query 사용 필요

2. Object 타입 이해하기

🔹 Object 타입이란?

  • JSON 객체 내부의 필드들을 독립적으로 색인
  • 하위 필드들을 분리하여 저장하기 때문에 부정확한 검색 결과 발생 가능

📌 예제 1: Object 타입 매핑 설정

PUT movie
{
  "mappings": {
    "properties": {
      "characters": {
        "properties": {
          "name": { "type": "text" },
          "age": { "type": "byte" },
          "side": { "type": "keyword" }
        }
      }
    }
  }
}

📌 예제 2: Object 데이터 저장

PUT movie/_doc/1
{
  "characters": {
    "name": "Iron Man",
    "age": 46,
    "side": "superhero"
  }
}

characters 객체 내부의 필드들이 각각 색인됨

📌 예제 3: Object 필드 검색

GET movie/_search
{
  "query": {
    "match": {
      "characters.name": "Iron Man"
    }
  }
}

Object 타입에서는 일반 Match Query 사용 가능


3. Object 타입의 문제점

Object 타입을 배열 형태로 저장할 때, 필드 간의 관계가 유지되지 않음

📌 예제 4: Object 타입을 배열로 저장

PUT movie/_doc/2
{
  "title": "The Avengers",
  "characters": [
    { "name": "Iron Man", "side": "superhero" },
    { "name": "Loki", "side": "villain" }
  ]
}

📌 예제 5: "Loki"이면서 "villain"인 문서 검색 (Object 타입)

GET movie/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "characters.name": "Loki" } },
        { "match": { "characters.side": "villain" } }
      ]
    }
  }
}

문제 발생: "Loki"가 "superhero"로 저장된 문서도 검색됨!

💡 이유:

  • Object 타입은 모든 필드를 개별적으로 저장
  • "characters.name": "Loki" 와 "characters.side": "villain"이 같은 객체인지 확인 불가능

4. Nested 타입으로 해결하기

🔹 Nested 타입이란?

  • JSON 객체 내부의 필드들을 하나의 단위로 저장
  • 각 객체를 별도 문서로 저장하여 관계 유지 가능
  • 검색 시 Nested Query를 사용해야 함

📌 예제 6: Nested 타입 매핑 설정

PUT movie
{
  "mappings": {
    "properties": {
      "characters": {
        "type": "nested",
        "properties": {
          "name": { "type": "text" },
          "side": { "type": "keyword" }
        }
      }
    }
  }
}

📌 예제 7: Nested 데이터 저장

PUT movie/_doc/3
{
  "title": "The Avengers",
  "characters": [
    { "name": "Iron Man", "side": "superhero" },
    { "name": "Loki", "side": "villain" }
  ]
}

📌 예제 8: "Loki"이면서 "villain"인 문서 검색 (Nested 타입)

GET movie/_search
{
  "query": {
    "nested": {
      "path": "characters",
      "query": {
        "bool": {
          "must": [
            { "match": { "characters.name": "Loki" } },
            { "match": { "characters.side": "villain" } }
          ]
        }
      }
    }
  }
}

정확한 문서만 검색됨!

💡 이유:

  • Nested 필드는 각 객체를 개별 문서처럼 저장
  • "characters.name": "Loki"와 "characters.side": "villain"이 같은 객체에 속하는지 확인 가능

5. Object vs Nested 비교

타입 특징 검색 방식
Object 객체 내부의 필드들이 개별적으로 색인됨 일반 Match Query 사용
Nested 객체 내부의 필드들이 한 단위로 유지됨 Nested Query 사용 필요
Object 필드 검색 문제 필드 간 관계가 유지되지 않아 부정확한 검색 결과 발생 가능 Loki가 superhero로 저장된 문서도 검색됨
Nested 필드 해결 객체 단위로 저장되어 정확한 검색 가능 Loki가 villain인 경우만 검색됨

6. 정리

Object 타입 JSON 객체의 필드를 독립적으로 저장 일반 Match Query 사용 가능
Nested 타입 JSON 객체 내부 필드 간 관계를 유지하여 저장 Nested Query 사용 필수
Object 타입 문제점 같은 필드 값이 포함된 다른 객체도 검색됨 잘못된 검색 결과 발생 가능
Nested 타입 해결책 각 객체를 별도 문서처럼 저장하여 관계 유지 정확한 검색 가능

7. 학습 가이드

1️⃣ Object 타입과 Nested 타입을 각각 사용하여 데이터를 저장하고 검색 실습
2️⃣ Object 타입에서 부정확한 검색 결과가 발생하는지 테스트
3️⃣ Nested Query를 사용하여 정확한 검색 결과 도출
4️⃣ Object 필드와 Nested 필드를 활용한 검색 최적화 연습


8. 마무리

Elasticsearch에서 Object와 Nested 타입을 올바르게 선택하는 것은 데이터 검색의 정확성을 결정하는 중요한 요소입니다.
Object 타입검색이 간편하지만 필드 관계를 유지하지 못함
Nested 타입객체 단위의 관계를 유지하지만, Nested Query를 사용해야 함

다음 학습에서는 Nested Query의 성능 최적화 및 Aggregation 활용법을 다루겠습니다! 🚀

Elasticsearch: Boolean(불리언) 타입 완벽 정리

Elasticsearch에서 Boolean(불리언) 타입true / false 값만을 저장할 수 있는 필드 타입입니다.
✔ true 또는 false 값 저장
✔ "true" 같은 문자열도 자동 변환됨
Term Query를 사용하여 검색

이번 글에서는 Boolean 타입의 기본 개념, 주요 옵션, 그리고 실전 적용 예제까지 상세히 알아보겠습니다.


1. Boolean 타입 개요

Boolean 타입은 논리적 참/거짓 값을 저장하는 데 사용됩니다.
✔ "true", "false", 1, 0 같은 값도 자동 변환되어 저장됩니다.

📌 예제 1: Boolean 필드 매핑 설정

PUT my_index
{
  "mappings": {
    "properties": {
      "is_active": {
        "type": "boolean"
      }
    }
  }
}

✅ "true", "1" → true로 저장됨
✅ "false", "0" → false로 저장됨


2. Boolean 타입 필드의 주요 옵션

Boolean 타입은 문자열, 숫자 필드와 일부 동일한 옵션을 가집니다.

옵션 설명 기본값
index 색인 여부 (검색 가능 여부) true
doc_values 집계/정렬을 위한 최적화된 저장 방식 사용 여부 true
null_value 필드가 존재하지 않을 때 기본값 설정 없음

3. Boolean 데이터 저장 및 검색 예제

📌 예제 2: Boolean 데이터 저장

PUT my_index/_doc/1
{
  "is_active": true
}
PUT my_index/_doc/2
{
  "is_active": "false"
}
PUT my_index/_doc/3
{
  "is_active": 1
}
PUT my_index/_doc/4
{
  "is_active": "0"
}

문자열 "false"도 false로 변환됨
숫자 1, "0"도 true, false로 변환됨


📌 예제 3: Boolean 값 검색 (Term Query 사용)

GET my_index/_search
{
  "query": {
    "term": {
      "is_active": true
    }
  }
}

✅ "is_active": true 인 문서만 검색됨


4. Boolean 필드에서 null_value 옵션 활용

✔ Boolean 필드가 null이거나 존재하지 않을 경우 기본값을 설정할 수 있음

📌 예제 4: Boolean 필드에서 null_value 설정

PUT my_index
{
  "mappings": {
    "properties": {
      "is_active": {
        "type": "boolean",
        "null_value": false
      }
    }
  }
}

✅ null 값이 입력되면 자동으로 false 처리됨

📌 예제 5: null_value 옵션 테스트

PUT my_index/_doc/5
{
  "is_active": null
}

✅ "is_active": null → 실제로는 false로 저장됨


5. 정리

개념 설명 예제
Boolean 타입 true 또는 false 값만 저장 가능 "true", "false", 1, 0
자동 변환 문자열 "true"도 true로 저장됨 "false" → false
Term Query 사용 Boolean 값 검색 시 Term Query 활용 "is_active": true 검색
null_value 필드가 null일 경우 기본값 설정 가능 null_value: false

6. 학습 가이드

1️⃣ Boolean 필드에 다양한 값(true, "false", 1, 0)을 저장하고 변환 결과 확인
2️⃣ Term Query를 활용하여 Boolean 값 검색 테스트
3️⃣ null_value 옵션을 사용하여 기본값 설정 및 동작 방식 확인


7. 마무리

Elasticsearch의 Boolean(불리언) 타입단순한 참/거짓 값을 저장하는 데 최적화되어 있으며,
✔ true, false, "true", "0" 등 다양한 값이 자동 변환됩니다.
✔ null_value 옵션을 활용하면 null 값 처리 시 기본값을 설정할 수 있습니다.

다음 학습에서는 Boolean 필드와 Filter Query를 활용한 검색 최적화 방법을 다루겠습니다! 🚀

Elasticsearch: 날짜(Date) 타입 완벽 정리

Elasticsearch에서 날짜(Date) 타입ISO8601 형식을 따르며, 다양한 날짜 포맷을 지원합니다.
ISO8601 기본 형식: "2019-06-12T17:13:40.428Z"
epoch_millis: 1970-01-01 00:00:00부터 경과한 밀리초
사용자 정의 포맷 설정 가능

이번 글에서는 날짜 타입의 기본 개념, 주요 옵션, 포맷 지정 방법, 그리고 Range Query 활용법까지 상세히 알아보겠습니다.


1. Elasticsearch에서 날짜(Date) 타입의 기본 개념

🔹 기본 날짜 형식 (ISO8601)

Elasticsearch는 ISO8601 형식을 기본적으로 지원합니다.

📌 자동으로 날짜로 인식되는 형식 예제

"2019-06-12"
"2019-06-12T17:13:40"
"2019-06-12T17:13:40+09:00"
"2019-06-12T17:13:40.428Z"

위 형식으로 입력하면 자동으로 날짜 타입으로 저장됨

📌 자동으로 문자열(text)로 저장되는 잘못된 날짜 형식 예제

"2019/06/12 12:10:30"  // "/" 사용 (기본 설정에서는 text로 저장됨)

이 경우 format 옵션을 설정해야 날짜로 저장 가능!


2. 날짜(Date) 타입 필드 설정

🔹 기본 날짜 타입 매핑 예제

PUT my_date
{
  "mappings": {
    "properties": {
      "date_val": {
        "type": "date"
      }
    }
  }
}

기본적으로 ISO8601 형식을 사용하며, long 타입의 epoch_millis도 저장 가능


3. 날짜(Date) 타입의 주요 옵션

Elasticsearch의 날짜 타입 필드는 문자열, 숫자 필드와 일부 동일한 옵션을 가집니다.

옵션 설명 기본값

옵션 설명 기본값
index 색인 여부 (검색 가능 여부) true
doc_values 집계/정렬을 위한 최적화된 저장 방식 사용 여부 true
null_value null 값이 입력될 경우 기본값 설정 없음
ignore_malformed 잘못된 날짜 입력 시 오류를 무시하고 저장할지 여부 false
format 날짜 입력 형식 지정 (여러 개 가능) `strict_date_optional_tim

4. 날짜 포맷 설정하기

기본적으로 Elasticsearch는 ISO8601 형식만 지원하지만,
format 옵션을 사용하여 다양한 날짜 형식을 추가할 수 있음

📌 예제 1: 다양한 날짜 형식 지원 (yyyy/MM/dd, yyyy-MM-dd HH:mm:ss, epoch_millis)

PUT my_date
{
  "mappings": {
    "properties": {
      "date_val": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
      }
    }
  }
}

지원되는 날짜 형식 예제

  • "2019-06-10 12:10:30"
  • "2019/06/10"
  • 1560127830000 (epoch_millis)

5. Elasticsearch에서 지원하는 날짜 포맷

다양한 날짜 포맷을 사용할 수 있으며, 아래와 같은 Joda-Time 심볼을 활용하여 설정할 수 있습니다.

📌 주요 날짜 포맷 심볼

심볼 의미 예제 (2019-09-12T17:13:07.428+09:00)
yyyy 년도 2019
MM 월(숫자) 09
MMM 월(문자, 3자리) Sep
MMMM 월(문자, 전체) September
dd 일(숫자) 12
a 오전/오후 PM
HH 24시간제 시간 (00~23) 17
hh 12시간제 시간 (01~12) 05
mm 분 (00~59) 13
ss 초 (00~59) 07
SSS 밀리초 428
Z 타임존 +09:00

6. 날짜 데이터 저장 및 검색 예제

📌 예제 2: 날짜 데이터 저장 (ISO8601)

PUT my_date/_doc/1
{
  "date_val": "2019-09-12 15:01:23"
}

✅ "2019-09-12 15:01:23"이 저장됨

📌 예제 3: Range Query (날짜 범위 검색)

GET my_date/_search
{
  "query": {
    "range": {
      "date_val": {
        "gt": "2019/09/10",
        "lt": 1568332800000
      }
    }
  }
}

다른 날짜 포맷을 사용해도 정상적으로 검색됨!

📌 예제 4: 현재 시간(now) 기준 검색

GET my_date/_search
{
  "query": {
    "range": {
      "date_val": {
        "gte": "now-1M",
        "lt": "now"
      }
    }
  }
}

최근 1개월 동안의 데이터 검색 가능


7. 날짜 데이터의 내부 저장 방식

모든 날짜 값은 내부적으로 epoch_millis (1970-01-01 00:00:00 UTC 기준 밀리초)로 변환하여 저장됨
✔ 하지만 검색 시에는 다양한 날짜 형식으로 조회 가능

📌 예제 5: _source 데이터 확인

GET my_date/_doc/1

🔹 결과 예제

{
  "_source": {
    "date_val": "2019-09-12 15:01:23"
  }
}

날짜 입력 값은 그대로 유지되지만, 내부적으로는 epoch_millis로 변환되어 저장됨


8. 정리

개념 설명
ISO8601 형식 기본 날짜 형식 (2019-06-12T17:13:40.428Z)
epoch_millis 1970-01-01 00:00:00 UTC부터의 밀리초 값
format 옵션 다양한 날짜 형식 지정 가능 (yyyy/MM/dd, epoch_millis 등)
현재 시간(now) 활용 now-1d, now-1M 같은 상대적 날짜 검색 가능
내부 저장 방식 모든 날짜는 epoch_millis로 변환 후 저장됨

9. 학습 가이드

1️⃣ ISO8601 형식 및 epoch_millis를 사용하여 데이터 저장 실습
2️⃣ format 옵션을 활용하여 다양한 날짜 형식 적용
3️⃣ Range Query를 사용하여 날짜 범위 검색 실습
4️⃣ 현재 시간(now) 기반 상대적 날짜 검색 테스트


10. 마무리

Elasticsearch의 날짜(Date) 타입다양한 포맷을 지원하며, epoch_millis로 변환하여 저장됩니다.
특히 format 옵션, range 쿼리, now 키워드를 활용하면 날짜 데이터를 효과적으로 관리할 수 있습니다.

다음 학습에서는 Range Query를 활용한 고급 날짜 검색 최적화 방법을 다루겠습니다! 🚀

Elasticsearch: 숫자 데이터 타입 (long, double, scaled_float 등) 완벽 정리

Elasticsearch는 **정수(Integer)와 실수(Float)**를 저장할 수 있도록 다양한 숫자 타입을 제공합니다.
정수 타입: long, integer, short, byte
실수 타입: double, float, half_float, scaled_float

이번 글에서는 각 숫자 타입의 특징, 주요 옵션, 그리고 실전 적용 예제까지 상세히 알아보겠습니다.


1. Elasticsearch에서 숫자 타입

🔹 기본 숫자 타입

Elasticsearch는 자바(Java)에서 사용되는 기본 숫자 타입을 지원합니다.

타입 설명 범위
long 64비트 정수 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
integer 32비트 정수 -2,147,483,648 ~ 2,147,483,647
short 16비트 정수 -32,768 ~ 32,767
byte 8비트 정수 -128 ~ 127
double 64비트 부동소수점 매우 큰 실수값 저장 가능
float 32비트 부동소수점 일반적인 실수 저장
half_float 16비트 부동소수점 작은 크기의 실수 저장
scaled_float 부동소수점을 정수(long)로 저장하며, 소수점 위치 지정 가능 scaling_factor 사용

2. 숫자 필드의 주요 옵션

Elasticsearch의 숫자 필드는 text, keyword와 일부 동일한 옵션을 가집니다.

옵션 설명 기본값
index 색인 여부 (검색 가능 여부) true
doc_values 집계/정렬을 위한 최적화된 저장 방식 사용 여부 true
boost 검색 시 가중치 부여 1
coerce 자동 형 변환 허용 여부 true
null_value null 값이 입력될 경우 기본값 설정 없음
ignore_malformed 잘못된 숫자 입력 시 오류를 무시하고 저장할지 여부 false

3. 정수(Integer) 타입 예제

📌 예제 1: 정수 타입 매핑 설정

PUT my_index
{
  "mappings": {
    "properties": {
      "price": {
        "type": "integer",
        "coerce": true
      }
    }
  }
}

🔹 설명:

  • "coerce": true → 4.5, "5" 등의 값도 4 또는 5로 자동 변환되어 저장됨 ✅

4. 실수(Floating Point) 타입 예제

📌 예제 2: 실수 타입 매핑 설정

PUT my_index
{
  "mappings": {
    "properties": {
      "rating": {
        "type": "float",
        "coerce": true
      }
    }
  }
}

🔹 설명:

  • "rating": 4.7 → 그대로 저장됨 ✅

5. Scaled Float (소수점 고정형 실수)

🔹 Scaled Float이란?

부동소수점을 정수(long)로 변환하여 저장
소수점 위치를 scaling_factor로 조정
금액($19.99)과 같은 고정 소수점 데이터에 유용

📌 예제 3: scaled_float 타입 매핑 설정

PUT my_index
{
  "mappings": {
    "properties": {
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}

🔹 설명:

  • "price": 19.99 → 1999로 변환 후 저장됨
  • "price": 100.25 → 10025로 저장됨

📌 주의:
scaling_factor: 100 이므로 두 자리 소수점까지 저장 가능

  • scaling_factor: 10 → 1자리 소수점까지만 저장 가능

6. 숫자 필드의 중요한 옵션 실전 예제

📌 예제 4: 숫자 필드에서 coerce, null_value, ignore_malformed 활용

PUT my_index
{
  "mappings": {
    "properties": {
      "quantity": {
        "type": "integer",
        "coerce": true,
        "null_value": 0,
        "ignore_malformed": true
      }
    }
  }
}

🔹 설명:

  • "coerce": true → "4.5", "6" 등의 값도 정수로 변환 ✅
  • "null_value": 0 → null 값이 입력되면 0으로 저장 ✅
  • "ignore_malformed": true → 숫자가 아닌 값이 입력되면 오류 없이 저장하되, 검색 및 집계에서 무시 ✅

7. 숫자 필드의 동적 매핑 문제점

숫자 필드를 동적으로 생성하면 위험할 수 있음
첫 번째 값이 4 같은 정수라면 long으로 자동 생성
✔ 이후에 5.5 같은 실수가 들어오면 자동 변환되지만 실제로는 5가 저장됨

📌 잘못된 동적 매핑 예제

PUT my_index/_doc/1
{
  "value": 4
}
PUT my_index/_doc/2
{
  "value": 5.5
}

🔹 문제:

  • value 필드가 long으로 자동 생성
  • 5.5가 입력되었지만 5로 저장됨 (소수점 손실 발생) ❗

해결 방법: 명시적 매핑 설정 사용!

PUT my_index
{
  "mappings": {
    "properties": {
      "value": {
        "type": "float"
      }
    }
  }
}

📌 이제 5.5가 올바르게 저장됨!


8. 정리

개념 설명
long, integer, short, byte 정수 타입 (64비트, 32비트, 16비트, 8비트)
double, float, half_float 부동소수점 실수 (정확도 차이)
scaled_float 부동소수점을 long 형태로 변환하여 저장 (scaling_factor 필요)
coerce 문자열 숫자를 자동 변환 ("4.5" → 4)
null_value null 값이 입력될 경우 기본값 설정
ignore_malformed 잘못된 숫자 입력 시 오류 없이 무시

9. 학습 가이드

1️⃣ 각 숫자 타입을 사용하여 데이터를 저장하고 검색하는 실습 진행
2️⃣ coerce, null_value, ignore_malformed 옵션을 활성화하고 동작 방식 실험
3️⃣ scaled_float을 활용하여 금액 데이터를 저장하고 검색 테스트
4️⃣ 동적 매핑으로 인한 문제를 직접 경험하고 해결 방법 적용


10. 마무리

Elasticsearch에서 숫자 타입을 올바르게 설정하는 것은 데이터의 정확성과 검색 성능을 높이는 중요한 요소입니다.
특히 정수 vs 실수, scaled_float 활용, 동적 매핑의 위험성을 이해하고 적절한 설정을 적용하는 것이 중요합니다.

다음 학습에서는 날짜(Date) 타입을 활용한 검색 및 최적화 방법을 다루겠습니다! 🚀

Elasticsearch: 문자열 타입 (text vs keyword) 완벽 이해

Elasticsearch에서는 문자열 데이터를 저장할 때 text 타입keyword 타입을 사용할 수 있습니다.
text: 검색을 위해 분석(Analyzed)되어 저장됨 (풀 텍스트 검색용)
keyword: 분석 없이 원본 그대로 저장됨 (정확한 값 검색 및 정렬, 집계용)

이 글에서는 text와 keyword의 차이, 각각의 주요 옵션, 그리고 실전 적용 예제까지 상세히 알아보겠습니다.


1. Elasticsearch에서 문자열 데이터 저장 방식

🔹 문자열 데이터 저장 방식의 변화

Elasticsearch 2.x 이전에는 문자열(string) 타입만 존재했으며, 분석 여부를 옵션으로 구분했습니다.
하지만 5.0 이후부터는 textkeyword 타입으로 나뉘면서, 텍스트 분석 여부를 명확히 구분하게 되었습니다.


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를 활용한 텍스트 분석 심화 과정을 다루겠습니다! 🚀

Elasticsearch: 매핑(Mappings) 이해하기

Elasticsearch에서 **매핑(Mappings)**은 인덱스 내 문서의 필드 유형 및 분석 방법을 정의하는 중요한 요소입니다.
동적 매핑(Dynamic Mapping): 자동으로 필드 타입을 생성
명시적 매핑(Explicit Mapping): 직접 필드 타입을 정의

이번 글에서는 매핑의 개념, 동적 매핑과 명시적 매핑의 차이, 그리고 필드 타입 설정 방법을 상세히 알아보겠습니다.


1. Elasticsearch의 매핑(Mappings) 개념

🔹 매핑이란?

  • Elasticsearch에서 문서의 각 필드에 대한 데이터 타입을 정의하는 과정입니다.
  • 인덱스를 생성할 때 매핑을 설정하면 필드의 타입을 명확히 지정하여 데이터의 일관성을 유지할 수 있습니다.
  • 매핑 정보는 GET <인덱스명>/_mapping 명령어로 확인할 수 있습니다.

📌 매핑 조회 예제

GET books/_mapping

🔹 결과 예제 (자동 매핑 적용 후)

{
  "books": {
    "mappings": {
      "properties": {
        "title": {
          "type": "text"
        },
        "author": {
          "type": "text"
        },
        "category": {
          "type": "keyword"
        },
        "publish_date": {
          "type": "date"
        },
        "pages": {
          "type": "long"
        }
      }
    }
  }
}

📌 설명:

  • title, author → text (검색 가능)
  • category → keyword (정확한 값 비교)
  • publish_date → date (ISO 8601 형식)
  • pages → long (정수)

2. 동적(Dynamic) 매핑

🔹 동적 매핑이란?

Elasticsearch는 새로운 필드가 문서에 추가될 경우 자동으로 매핑을 생성하는 기능을 제공합니다.
즉, 사전에 필드를 정의하지 않아도 문서를 색인하면 자동으로 매핑이 설정됩니다.

📌 예제 1: books 인덱스 없이 문서 입력

PUT books/_doc/1
{
  "title": "Romeo and Juliet",
  "author": "William Shakespeare",
  "category": "Tragedies",
  "publish_date": "1562-12-01T00:00:00",
  "pages": 125
}

📌 자동 매핑 결과 확인

GET books/_mapping

🔹 자동 매핑 결과

  • title, author: text
  • category: keyword
  • publish_date: date
  • pages: long

3. 명시적(Explicit) 매핑

🔹 명시적 매핑이란?

  • 데이터가 인덱싱되기 전에 필드 타입을 미리 정의하는 방식입니다.
  • 자동 매핑은 필드 타입이 의도와 다르게 설정될 수 있으므로, 중요한 필드는 명시적으로 설정하는 것이 좋습니다.
  • 특히 숫자, 날짜, 키워드 필드는 명확한 설정이 필요합니다.

📌 예제 2: 명시적 매핑 설정

PUT books
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "author": {
        "type": "text"
      },
      "category": {
        "type": "keyword"
      },
      "publish_date": {
        "type": "date"
      },
      "pages": {
        "type": "integer"
      }
    }
  }
}

🔹 설명

  • title, author: text (검색 최적화)
  • category: keyword (필터링 및 정렬 가능)
  • publish_date: date (날짜 필드)
  • pages: integer (정수값)

📌 새로운 문서 입력 (매핑 유지됨)

PUT books/_doc/2
{
  "title": "Hamlet",
  "author": "William Shakespeare",
  "category": "Tragedies",
  "publish_date": "1603-01-01T00:00:00",
  "pages": 200
}

📌 매핑 확인

GET books/_mapping

🔹 결과: 기존 설정된 필드 타입이 유지됨 ✅


4. 기존 인덱스에 필드 추가

Elasticsearch에서는 기존 인덱스에 새로운 필드를 추가할 수 있지만, 기존 필드의 타입 변경은 불가능합니다.

📌 예제 3: 기존 인덱스에 publisher 필드 추가

PUT books/_mapping
{
  "properties": {
    "publisher": {
      "type": "keyword"
    }
  }
}

📌 매핑 확인

GET books/_mapping

🔹 결과: publisher 필드가 keyword 타입으로 추가됨 ✅

하지만 기존 필드의 타입 변경은 불가능

PUT books/_mapping
{
  "properties": {
    "pages": {
      "type": "float"  ❌ (에러 발생)
    }
  }
}

이미 설정된 필드 타입은 변경 불가능 → 새로운 인덱스를 만들어 데이터를 재색인해야 함


5. 주요 데이터 타입 정리

Elasticsearch에서 사용할 수 있는 주요 데이터 타입을 정리하면 다음과 같습니다.

데이터 타입 설명
text 전문 검색(Full-Text Search)용 필드
keyword 정확한 값 비교, 필터링, 정렬
integer 정수값
long 큰 정수값
float 소수점 포함 숫자
double 높은 정밀도의 소수점 숫자
date 날짜 필드 (ISO 8601)
boolean true/false 값
object JSON 객체 저장
nested 다중 필드(Nested Documents)

6. 정리

개념 설명
동적 매핑 (Dynamic Mapping) 문서가 입력될 때 자동으로 필드 타입을 생성
명시적 매핑 (Explicit Mapping) 필드 타입을 사전에 정의하여 데이터의 일관성 유지
기존 인덱스에 필드 추가 가능 여부 ✅ 새로운 필드는 추가 가능
기존 필드 타입 변경 가능 여부 ❌ 기존 필드 타입 변경 불가능 (재색인 필요)

7. 학습 가이드

1️⃣ 동적 매핑과 명시적 매핑을 비교하며 실습
2️⃣ 다양한 필드 타입을 정의하고 검색 결과 비교
3️⃣ keyword와 text 필드의 차이를 이해하고 적절히 사용
4️⃣ 기존 필드 타입 변경이 불가능하므로, 새로운 인덱스를 생성하고 데이터 재색인 연습


8. 마무리

Elasticsearch에서 **매핑(Mappings)**은 데이터를 효율적으로 저장하고 검색하는 데 중요한 역할을 합니다.
특히 keyword vs text, 동적 매핑 vs 명시적 매핑, 기존 필드 타입 변경 불가능 등의 개념을 이해하고 올바르게 활용하는 것이 중요합니다.

다음 학습에서는 Nested & Object 타입을 활용한 문서 구조 설계 방법을 다루겠습니다! 🚀

Elasticsearch: 설정(Settings) 이해하기

Elasticsearch에서 **인덱스를 생성할 때 필요한 설정(Settings)**은 매우 중요한 요소입니다.
모든 인덱스는 두 개의 핵심 정보 단위를 가지며,
Settings (설정): 인덱스의 기본적인 동작을 정의
Mappings (매핑): 필드의 데이터 유형과 분석 방법을 지정

이번 글에서는 Settings의 개념, 주요 설정 요소, 그리고 변경 가능 여부에 대해 상세히 알아보겠습니다.


1. Elasticsearch Settings란?

🔹 기본 개념

  • Settings는 Elasticsearch 인덱스의 구성 및 동작을 정의하는 설정 값입니다.
  • 주요 설정에는 샤드(Shard) 개수, 복제본(Replica) 개수, 리프레시 간격(refresh_interval), 애널라이저(analyzer) 등이 포함됩니다.
  • 인덱스를 생성할 때 설정되며, 일부 설정은 운영 중에도 변경 가능하지만, 일부는 한 번 설정되면 변경 불가능합니다.

📌 인덱스 정보 조회 예제

GET my_index

🔹 결과:

  • settings → 인덱스의 설정 정보
  • mappings → 필드 타입 및 매핑 정보

📌 설정만 따로 조회

GET my_index/_settings

📌 매핑 정보만 따로 조회

GET my_index/_mappings

2. 샤드(Shard)와 복제본(Replica) 설정

🔹 샤드(Shard)란?

  • Elasticsearch의 인덱스는 여러 개의 샤드(Shard)로 분할 저장됩니다.
  • 기본적으로 하나의 인덱스는 **프라이머리 샤드(Primary Shard)와 복제 샤드(Replica Shard)**로 구성됩니다.

설정 값 설명 기본값

number_of_shards 인덱스의 프라이머리 샤드 개수 7.x부터 기본값 1
number_of_replicas 복제본 개수 (프라이머리 샤드 당) 7.x부터 기본값 1

📌 샤드 & 복제본 설정 예제

PUT my_index
{
  "settings": {
    "index": {
      "number_of_shards": 3,
      "number_of_replicas": 1
    }
  }
}

🔹 샤드 개수 변경 가능 여부

  • number_of_replicas운영 중 변경 가능
  • number_of_shards인덱스 생성 후 변경 불가

📌 복제본 개수 변경 예제

PUT my_index/_settings
{
  "number_of_replicas": 2
}

📌 샤드 개수 변경이 필요한 경우
샤드 개수를 변경하려면 새로운 인덱스를 생성하고 기존 데이터를 다시 색인(reindexing) 해야 합니다.


3. Refresh Interval 설정

🔹 Refresh Interval이란?

  • Elasticsearch는 새로운 문서를 색인한 후 일정 주기로 검색 가능하도록 처리합니다.
  • 이 주기를 refresh interval이라고 하며, 기본값은 1초(1s) 입니다.
  • 값을 늘리면 색인 성능이 향상되지만, 검색 반영이 느려질 수 있음

📌 refresh_interval 설정 예제 (30초로 변경)

PUT my_index
{
  "settings": {
    "refresh_interval": "30s"
  }
}

📌 운영 중 refresh_interval 변경 가능

PUT my_index/_settings
{
  "refresh_interval": "5s"
}

색인 작업이 많을 때는 "refresh_interval": "-1" 로 설정하여 자동 리프레시를 비활성화하고, 배치 색인 후 POST my_index/_refresh 를 실행하여 직접 리프레시할 수도 있습니다.


4. Analyzer, Tokenizer, Filter 설정

Elasticsearch에서 **애널라이저(Analyzer)**를 설정하려면 settings 내부의 analysis 항목을 사용합니다.

📌 사용자 정의 애널라이저 설정 예제

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "char_filter": [ "html_strip" ],
          "tokenizer": "standard",
          "filter": [ "lowercase", "stop" ]
        }
      }
    }
  }
}

🔹 설명

  • "type": "custom" → 사용자 정의 애널라이저
  • "char_filter": ["html_strip"] → HTML 태그 제거
  • "tokenizer": "standard" → 기본 토큰화
  • "filter": ["lowercase", "stop"] → 소문자 변환, 불용어(stopword) 제거

🔹 Analyzer 변경 가능 여부

  • 애널라이저 설정(analysis)은 변경 불가능
  • 변경하려면 인덱스를 close → 설정 변경 → 다시 open 해야 함

📌 애널라이저 변경 방법

POST my_index/_close
PUT my_index/_settings
{
  "analysis": {
    "analyzer": {
      "new_analyzer": {
        "type": "custom",
        "tokenizer": "whitespace"
      }
    }
  }
}
POST my_index/_open

❗ 하지만 이미 존재하는 필드의 분석 방식은 변경할 수 없음새로운 인덱스를 만들고 데이터를 다시 색인해야 함


5. 정리

설정 값 설명 변경 가능 여부
number_of_shards 인덱스의 프라이머리 샤드 개수 ❌ 변경 불가
number_of_replicas 프라이머리 샤드 당 복제본 개수 ✅ 변경 가능
refresh_interval 색인된 데이터가 검색 가능해지는 주기 ✅ 변경 가능
analysis (Analyzer) 텍스트 분석기 설정 ❌ 변경 불가 (재색인 필요)

6. 학습 가이드

1️⃣ 샤드와 복제본 개수 설정 방법 실습
2️⃣ refresh_interval을 변경하며 색인 성능 테스트
3️⃣ 사용자 정의 애널라이저를 설정하고 분석 결과 확인
4️⃣ Analyzer 변경 불가 원리를 이해하고, 새로운 인덱스로 재색인 연습


7. 마무리

Elasticsearch의 Settings는 인덱스의 성능과 검색 효율성을 결정하는 중요한 요소입니다.
특히 샤드와 복제본 개수, Refresh Interval, 분석기 설정을 이해하고 적절히 활용하는 것이 중요합니다.

다음 학습에서는 Mappings을 활용한 필드 타입 및 데이터 구조 정의 방법을 다루겠습니다! 🚀

+ Recent posts