Elastic Search

[Elasticsearch] 매핑과 인덱스 alias, template

꾸준함. 2024. 6. 6. 15:28

매핑

  • 관계형 데이터베이스에서 스키마와 비슷한 개념
    • RDBMS에서 스키마는 테이블을 구성하는 구성요소 간의 논리적인 관계와 정의
    • Elasticsearch에서는 JSON 형태의 데이터를 Apache Lucene이 이해할 수 있도록 바꿔주는 작업
    • Elasticsearch가 검색 엔진으로 전문 검색과 대용량 데이터를 빠르게 실시간 검색할 수 있는 이유는 매핑이 있기 때문인데 매핑을 엘라스틱 서치가 자동으로 하면 동적 매핑, 사용자가 직접 설정하면 정적 매핑 혹은 명시적 매핑

 

  • Elasticsearch의 인덱스에 들어가는 데이터의 타입을 정의하며 인덱스에 추가되는 데이터의 유형을 결정
  • 매핑을 지정하지 않아도 동적으로 매핑이 생성되지만 실무에서는 미리 저장할 필드들을 파악하고 정적 매핑 하는 것을 권장
  • 인덱스 및 데이터 유형을 정의하기 위해서는 정적 매핑 사용

 

동적 매핑과 정적 매핑

 

1. 동적 매핑

  • 문서를 색인할 때 필드명과 유형을 구성할 필요 없고 Elasticsearch에서 자체적으로 타입을 추론하여 매핑
    • 문서 색인 시 신규 필드가 유입되면 동적 매핑을 사용하여 필드의 데이터 유형을 결정하고 신규 필드 추가

 

  • 동적 매핑 규칙을 동적필드 매핑 또는  동적 템플릿을 사용하여 구성해 기존 매핑을 사용자 지정할 수 있음
  • 새로운 필드 생성 시 문서를 색인하고 동적으로 필드를 생성할지 결정하는 파라미터 설정 가능
  • 필드 타입이 잘 못 정의되어 검색 시 오류를 일으킬 가능성이 있음 (ex 날짜 타입)
    • 실제로 정합성 및 검색 품질 높이기 위해 인덱스 생성 시 혹은 데이터 변경 시 정적 매핑 추천

 

1.1 동적 매핑 세팅 - dynamic 파라미터

 

옵션 설명
true default 옵션으로 새로운 필드를 매핑에 생성
runtime 새로운 필드를 매핑에 런타임 필드로 추가
필드가 추가는 되지만 색인되지 않고 _source 쿼리 시 로드 됨
false 새로운 필드는 무시되고 매피에 추가되지 않음
색인되거나 검색할 수는 없지만, _source로 변환된 필드에는 표시 됨
strict 새로운 필드가 감지되면 예외가 발생하고 문서가 색인되지 않음
매핑에 명시적으로 새로운 필드르 추가해야 됨

 

 

1.1.1 파라미터가 strict인 경우 예시

 

 

 

부연 설명

  • 새로운 필드 감지 시 아래와 같이 예외가 발생함

 

strict

 

1.2 동적 매핑 기준

 

원본 소스 데이터 타입 동적 매핑으로 변환된 데이터 타입
null 필드 추가 X
boolean boolean
float float
integer long
object object
string string 데이터 형태에 따라
1. date
2. text/keword 멀티 필드

 

 

동적 매핑 시 주의할 점

  • 개발 단계에서 스키마 설계를 고민하기보다 데이터의 형태만 고민하면 되므로 무척 편하지만
    • 숫자 타입은 무조건 범위가 가장 넓은 long으로 매핑되어 불필요한 메모리를 차지하여 데이터가 많을 경우 성능 저하를 유발할 수 있음
    • 문자열의 경우 검색과 정렬 등을 고려한 매핑이 제대로 되지 않을 수 있음

 

2. 정적/명시적 매핑

  • 문서에 저장할 데이터의 종류를 미리 알고 있어 인덱스를 생성할 때 필드와 유형을 직접 정의
  • 인덱스를 생성할 때 mappings 정의를 설정하거나 mapping API를 이용해 매핑을 지정할 수 있음
    • 인덱스 생성 시 mappings.properties 아래에 필드명과 필드 타입을 지정해 주면 됨

 

  • 정의된 필드를 삭제하거나 데이터 필드 유형을 실시간으로 변경하는 것은 불가능
    • 필드명을 변경하거나 데이터 타입을 변경하기 위해서는 새로운 인덱스를 만들거나 reindex API를 이용해야 하므로 매핑 작업은 신중하게 하는 것을 권장

 

 

* properties 파라미터 외엥도 analyzer나 format 등을 설정하는 파라미터도 있으므로 공식 문서 참조하는 것을 권장

 

 

3. 매핑 타입

  • 명시적 매핑을 위해서는 Elasticsearch에서 사용하는 데이터 타입에 대한 이해가 요구됨
  • 좋은 스키마가 관계형 데이터베이스의 성능을 끌어올리는 것처럼 매핑을 잘 활용하면 Elasticsearch의 인덱스 성능을 올릴 수 있음

 

데이터 형태 데이터 타입 설명
텍스트 text 전문 검색이 필요한 데이터로 텍스트 분석기가 텍스트를 작은 단위로 분리
keyword 정렬이나 집계에 사용되는 텍스트 데이터로 분석을 하지 않고 원문을 통째로 색인
날짜 date 날짜/시간 데이터
정수 byte, short,
integer, long
byte: 부호 있는 8비트 데이터
short: 부호 있는 16비트 데이터
integer: 부호 있는 32비트 데이터
long: 부호 있는 64비트 데이터
실수 scaled_float,
half_float,
double,
float
scaled_float: float 데이터에 특정 값을 곱해서 정수형으로 바꾼 데이터, 정확도는 떨어지나 필요에 따라 집계 등에서 효율적으로 사용 가능
half_float: 16비트 부동소수점 실수 데이터
float: 32비트 부동소수점 실수 데이터
double: 64비트 부동소수점 실수 데이터
불린 boolean 참/거짓 데이터로 true/false만을 값으로 가짐
IP 주소 ip ipv4, ipv6 타입 IP 주소를 입력할 수 있음
위치 정보 geo_point,
geo_shape
geo_point: 위도, 경도 값을 가짐
geo_shape: 하나의 위치 포인트가 아닌 임의의 지형
범위 값 integer_range,
long_range,
float_range,
double_range,
ip_range,
date_range
범위를 설정할 수 있는 데이터
integer_range, long_range는 정수형 범위
float_range, double_range는 실수형 범위
ip_range는 IP 주소 범위
date_range는 날짜/시간 데이터 범위 값을 저장하고 검색할 수 있게 함
최솟값과 최댓값을 통해 범위를 입력
객체형 object 계층 구조를 갖는 형태로 필드 안에 다른 필드들이 들어갈 수 있음
배열형 nested 배열형 객체를 저장
객체를 따로 색인하여 객체가 하나로 합쳐지는 것을 막고, 배열 내부의 객체에 쿼리로 접근 가능
join 부모(parent)/자식(child) 관계를 표현할 수 있음

 

4. 다양한 필드 타입 유형

 

4.1 keyword 필드 타입 유형

  • 검색 시 aggregations, term level query, sorting 항목에서 사용
  • analyzer를 사용하지 않고 원문 데이터를 그대로 색인
    • 입력된 문자를 하나의 토큰으로 저장
    • 검색 시 입력된 문자와 동일한 문자가 입력되어야 검색됨
    • 공백, 대소문자 등을 구분하지 않기 때문에 서로 다른 키워드로 인식되어 정확하게 질의

 

  • keyword, constant_keyword, wildcard 타입으로 설정
  • 주로 다음과 같은 항목에 사용됨
    • 이메일
    • 태그
    • 카테고리
    • 정렬이 필요한 항목
    • 집계(aggregations)가 되어야 하는 항목

 

4.1.1 keyword 필드 타입의 주요 매개변수

 

매개변수 설명
normalizer analyzer와 비슷한 역할이지만 형태소 분석을 수행하지 않음
색인되는 문자열의 전처리

ex) cafe, Cafe, Cafè 모두 같은 "cafe"로 색인되게 하기 위해서는 lowercase filter를 사용하는 normalizer 정의
doc_values 정렬, 집계 등을 하기 위해 on-disk data 구조로 열 기반 저장소에 저장할지를 결정
boost 필드 가중치를 부여하며 가중치에 따라 유사도 점수가 달라짐
검색 시 결과나 순위에 영향을 끼침
field 동일한 문자열로 여러 번 색인을 수행할 수 있도록 하위 필드를 정의
같은 문자에 다른 분석기 사용
null_value null 값일 때 대체할 단어를 결정

 

 

4.1.2 constant_keyword 필드 타입

  • 색인 시 모든 문서가 동일한 값을 색인
  • 필터링 속도를 높이는데 사용

 

 

 

부연 설명

  • 모든 문서에서 sale_status가 항상 "sale"
  • 같은 값을 반복해서 저장할 필요가 없으므로, 저장 공간과 메모리를 절약
  • 모든 문서에서 동일한 값을 가지기 때문에 검색 속도가 매우 빠름

 

4.1.3 wildcard 필드 타입

  • 내부적으로 wildcard 필드는 n-gram을 적용하여 전체 필드 값을 색인하고 전체 문자열 저장
  • 검색 속도는 느림
  • 구조화 되지 않은 컨텐츠가 포함된 필드를 keyword 필드에 매핑
  • wildcard, regexp 쿼리에서 사용되며 *, ?와 같은 형태로 사용

 

4.2 text 필드 타입 유형

  • analyzer의 분석 프로세스를 통해 전체 텍스트를 개별 단어로 만들어 검색
    • analyzer를 사용하여 토큰을 분리 한 후 저장
    • ex) 볼보XC60 -> [볼보, XC60]
    • 분해된 단어만 입력해도 관련 있는 문서 검색이 가능

 

  • 별도의 analyzer를 지정하지 않을 경우 standard analyzer가 분석기로 지정됨
    • 한글 형태소 분석기를 사용하기 위해 검색에 사용할 분석기를 별도로 인덱스 settings에 지정 가능
    • 색인에 사용할 분석기와 검색에 사용할 분석기를 별도로 지정 가능

 

4.2.1 text 필드 타입의 주요 매개변수

 

매개변수 설명
analyzer 색인 시 사용할 분석기 지정
search_analyzer를 지정하지 않을 경우 같은 분석기로 구성
analyzer를 지정하지 않을 경우 standard analyzer 사용
search_analyzer 검색 시 사용할 분석기를 지정하는 매개변수이며 analyzer와 같은 분석기 사용 가능
보통은 동의어 등의 구성 때문에 다른 분석기로 사용
fielddata text 필드를 집계 또는 정렬을 사용할 수 있게 설정
dynamic 설정으로 매핑을 업데이트하여 변경 가능
true로 설정 시 메모리 사용량이 많기 때문에 keyword 타입을 field 파라미터로 생성하여 사용하는 것을 권장

 

4.2.2 match_only_text 필드 타입

  • 로그 분석 시 사용하는 text 필드
  • 일반 text 필드에 비해 디스크 공간을 10% 절약
  • keyword 필드와 text 필드의 중간 단계
  • 전체 텍스트 쿼리를 실행하지만 결과에 관련 score 값을 생성하지 않아 빠름
  • standard analyzer에서만 사용 가능

 

4.2.3 search_as_you_type 필드 타입

  • n-gram 분석기를 사용하여 전방 일치 혹은 중간 일치를 할 수 있게 하는 데이터 타입
  • 매핑에 구성한대로 분석/분석기가 구성되지 않을 경우 standard analyzer 사용

 

4.3 멀티 필드 유형

  • Elasticsearch 5.x 버전부터 string 타입이 text와 keyword라는 두 가지 타입으로 분리됨
  • string 타입을 동적 매핑하면 멀티 필드가 적용되어 두 타입 모두 생성됨
    • 공간을 절약하고 쓰기 속도를 높이기 위해 색인 전 매핑을 설정하는 것이 유리

 

  • 단일 필드 입력에 대해 여러 하위 필드를 정의하는 기능으로 이를 위해 fields라는 매핑 파라미터가 사용됨
    • fields는 하나의 필드를 여러 용도로 사용할 수 있게 만들어줌
    • 문자열의 경우 전문 검색이 필요하면서 정렬도 필요한 경우도 있음
    • 또한 처음 데이터 스키마를 잡는 시점에서는 키워드 타입으로 충분히 처리가 가능한 범주형 데이터였지만 데이터가 늘어나면서 전문 검색이 필요해지는 경우도 생김
    • 위와 같은 케이스들에서는 text와 keyword를 동시에 지원해야 함

 

멀티 필드

 

4.4 array 필드 타입 유형

  • Elasticsearch에 별도의 배열 타입이 존재하지 않음
  • 배열로 생성된 값은 동일한 타입을 가져야 하며 기본적으로 모든 데이터는 배열로 문서를 생성할 수 있음
    • ex) [-1, 1]
    • ex) [{id: 1}, {id: 2}, {id: 3}]
    • ex) ["볼보", "XC60"]

 

4.5 numeric 필드 타입 유형

  • 자바에서 사용하는 숫자형 데이터 타입을 지원
  • 작은 수의 타입을 사용해야 색인 및 검색을 효율적으로 수행
    • 동적 매핑 적용 시 모든 필드를 수용할 수 있도록 큰 타입으로 지정되어 메모리 낭비 유발할 수 있음 (long, double)

 

4.6 date 필드 타입 유형

  • 내부적으로 Date 타입은 UTC로 변환되며 내부적으로는 UTC의 밀리초로 변환되어 저장
  • JSON에서 date 타입은 문자열로 표현됨
  • 매핑 설정 시 문자열 format을 명시해야 함
    • default format: "yyyy-MM-ddTHH:mm:ssZ"

 

  • 여러 개의 포맷을 동시에 매핑 설정 가능
    • ex) "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"

 

4.7 range 필드 타입 유형

  • 검색 시 relation 필드를 사용
  • 범위의 연속된 데이터를 저장
    • 시작과 끝 값만 지정
    • ex) 게시물의 게시 기간
    • ex) 허용 IP 범위
    • ex) 가격 필터

 

 

4.8 geo_spatial 필드 타입 유형

  • 위/경도 등 위치 정보를 담은 데이터를 저장
    • ex) 반경 내 쿼리
    • ex) 위치 기반 집계
    • ex) 위치 별 정렬 등 작업
    • ex) 지리적으로 중심점으로부터 거리 별 문서 집계 및 정렬

 

4.8.1 geo 필드 타입 유형

  • geo 필드 타입을 설정할 경우 동적 매핑이 되지 않음
  • 위도와 경도를 사용하여 geo_point 필드 타입을 정의
  • geo_shape 필드는 하나의 위치 포인트가 아닌 임의의 지형

 

4.9 Object 필드 타입 유형

  • JSON 포맷은 내부 객체를 계층으로 표현
  • 내부적으로는 flat한 형태로 key-value 쌍으로 변경하여 저장

 

 

4.10 Nested 필드 타입 유형

  • Object 필드 타입의 특화 버전
  • Object Array를 저장하기 위해 사용
  • 배열로 Object를 저장하면 각각의 Object는 독립성을 유지
  • 저장된 각각의 Object 별 문서 조회 가능
    • nested query를 사용하여 검색어 질의

 

 

4.10.1 Object vs Nested 필드 타입 유형

  • Object 필드도 array 형태로 저장 가능하지만 문서의 개별성을 보장하는가의 차이가 존재
  • Object 필드에 대해서는 korean-name: "닷지", english_name: "hyundai"로 질의해도 결과 반환
  • 반면 Nested 필드에 대해서는 korean-name: "닷지", english_name: "hyundai"로 질의하면 결과 반환 X
    • korean_name: "닷지", english_name: "durango"가 한 쌍
    • korean_name: "현대", english_name: "hyundai"가 한 쌍
    • Nested 필드는 각각의 Object를 독립적으로 저장하기 때문에 key-value 쌍이 맞아야 결과 반환

 

4.11 dense vector 필드 타입 유형

  • float 형태의 value로 저장됨
  • script score 쿼리 혹은 KNN search API를 사용하여 유사한 벡터를 검색할 때 사용
    • HNSW 알고리즘을 사용하여 KNN 검색 지원
    • ex) 이미지 검색의 유사도 측정
    • KNN으로 vector 색인 시 색인되는 시간이 오래 걸릴 수 있음

 

4.11.1 dense vector 필드 타입 매개변수

 

매개변수 설명
type KNN 알고리즘 유형 (HNSW만 지원)
m hnsw 그래프에서 각 노드가 연결된 근접 이웃 수
기본값은 16으로 숫자가 클 수록 색인 속도가 느려지지만 정확도는 상승
ef_construction 최근접 이웃의 목록을 조합하는데 추적할 후보 수
기본값은 100, 숫자가 클 수록 검색 속도가 느려지지만 정확도는 상승
dims 벡터 차원수 2048을 초과할 수 없음
index 필드를 검색 할 지에 대한 여부
similarity KNN에서 사용할 vector 유사도 메트릭 (l2_norm, dot_product, cosine) 사용 가능

 

 

 

인덱스 alias 정의

  • 인덱스명을 대체할 인덱스명으로 사용할 수 있음
  • 여러 인덱스를 연결하여 하나의 인덱스처럼 사용할 수 있음
  • 신규 인덱스에 색인하고 alias를 사용하여 다운타임 없이 인덱스 교체 가능
  • _alias API를 사용하여 인덱스에 세팅

 

https://medium.com/hello-elasticsearch/elasticsearch-c8c9c711f40

 

1. 인덱스 alias 추가/조회

  • PUT [인덱스]/_alias/[새로운 alias명]
  • 인덱스에 alias를 추가하거나 삭제를 간단하게 하는 기능
  • alias를 조회 시 매핑되어 있는 인덱스를 확인 가능

 

alias를 통해 조회 가능

 

2. 인덱스 alias 삭제

  • DELETE [인덱스]/_alias/[삭제할 alias명]

 

DELETE car-master.static.alias/_alias/car-master-reader

 

3. 인덱스 alias 한번에 추가 및 삭제

  • POST _aliases
  • 무중단으로 인덱스를 변경하기 위해 한번에 인덱스 alias를 추가하고 삭제


 

 

4. 인덱스 라이프 사이클

  • 인덱스를 mapping과 setting 정보와 함께 생성
  • 신규 인덱스에 write alias를 연결
  • write alias에 데이터 색인
  • read alias를 신규 인덱스로 변경 후 기존 인덱스 삭제 혹은 close api를 통해 비활성화

 

인덱스 템플릿

  • 매번 같은 패턴으로 생성되는 인덱스를 정의하기 위해 매핑과 세팅을 정의하지 않고 자동으로 인덱스 구성
  • template을 지정할 경우 옵션에 따라 우선순위를 정의할 수 있음
  • 자동으로 생성되는 인덱스 및 실시간으로 데이터를 저장하는 로그성 데이터의 인덱스 생성 시 용이
  • 템플릿은 인덱스명과 템플릿에 정의된 인덱스 조건의 이름이 맞으면 정의된 구성으로 인덱스 생성
  • 사용자 정의 구성으로 인덱스를 생성할 수 있음
    • mappings: 필드의 스키마 정의
    • settings: 샤드의 크기 등 인덱스와 관련된 세팅 정의
    • aliases: 인덱스 생성 시 인덱스의 별칭 지정

 

1. 템플릿 유형

 

1.1 index 템플릿

  • _index_template API를 사용
  • 정적으로 인덱스에 대한 템플릿을 구성하고 인덱스 패턴에 따라 인덱스의 정보를 저장

 

 

부연 설명

  • "index_patterns": ["car-master.*"]는 이 템플릿이 적용될 인덱스의 이름 패턴을 지정하며 car-master.* 패턴을 가진 모든 인덱스가 해당
  • "priority": 1은 이 템플릿의 우선 순위를 나타내며 여러 템플릿이 동일한 인덱스 패턴에 적용될 수 있는 경우, 우선순위가 높은 템플릿이 우선 적용됨
  • template 섹션은 템플릿이 적용될 때 사용할 구체적인 설정과 매핑을 정의

 

1.2 component 템플릿

  • _component_template API 사용
  • 필요한 구성을 정의하고 자체적으로 재사용 가능한 템플릿
  • 하나 이상의 템플릿과 연결 될 수 있음
    • 인덱스 템플릿은 인덱스 별로 묶이기 때문에 같은 이름의 필드 구성 요소를 재사용할 수 없음
    • 인덱스 템플릿으로 정의된 인덱스와 유사한 인덱스 생성 시 전체 템플릿을 다시 생성해야 함


 

부연 설명

  • "index_patterns": ["car-sub.*"]는 이 템플릿이 적용될 인덱스의 이름 패턴을 지정하며 car-sub.* 패턴을 가진 모든 인덱스가 해당됨
  • "priority": 0은 이 템플릿의 우선 순위를 나타내며 우선순위가 낮을수록 다른 템플릿에 의해 덮어 쓰일 가능성이 높음
    • 이 템플릿의 우선 순위는 0이므로 기본값으로 낮은 우선순위를 가짐

 

  • "composed_of": ["settings-template", "mapping-template", "aliases-template"]는 이 템플릿이 구성 요소 템플릿으로부터 설정, 매핑, 별칭을 가져와서 조합한다는 것을 나타냄

 

https://opster.com/guides/elasticsearch/data-architecture/index-composable-templates/

 

2. 다이내믹 템플릿

  • 매핑을 동적으로 지정하는 템플릿 기술
  • 로그 시스템이나 비정형화된 데이터처럼 필드 타입을 정확히 정의하기 힘들고, 필드 개수를 정할 수 없는 경우 유용한 템플릿
    • 다이내믹 템플릿은 이처럼 매핑을 정확하게 정할 수 없거나 대략적인 데이터 구조만 알고 있을 때 사용할 수 있는 방법

 

 

부연 설명

  • my_string_fields는 임의로 정의한 다이내믹 템플릿명이며 다이내믹 템플릿명 밑으로 2개의 설정 존재
    • match_mapping_type은 조건문 혹은 매핑 트리거이며 여기서는 문자열 타입 데이터가 있으면 조건이 만족되어 트리거링 됨
    • mapping은 실제 매핑을 적용하는 부분이며 문자열 타입의 데이터가 들어오면 keyword 타입으로 매핑

 

 

부연 설명

  • name 필드는 문자열 타입이기 때문에 다이나믹 템플릿에서 설정한 대로 keyword 타입으로 매핑
  • age 필드는 numeric 타입이기 때문에 long 타입으로 동적 매핑

 

3. 템플릿 삭제

  • DELETE _index_template/[템플릿명]

 

참고

  • 패스트 캠퍼스 -  고성능 검색 엔진 구축으로 한 번에 끝내는 Elasticsearch
  • 엘라스틱 개발부터 운영까지 (김준영, 정상운 저)
반응형

'Elastic Search' 카테고리의 다른 글

[Elasticsearch] 검색  (0) 2024.06.07
[Elasticsearch] 분석기(analyzer)  (3) 2024.06.07
[Elasticsearch] 데이터 모델링 기초  (0) 2024.06.06
[Elasticsearch] 개념과 용어 정리  (1) 2024.06.02
[Elasticsearch] 설정 관련 정리  (0) 2022.11.16