반응형

Mapping

  • Elasticsearch에서는 index에 document 형태로 데이터들을 정의한다. 
  • 이때, index(DB의 테이블에 해당)에 저장될 document(DB의 각 row에 해당)의 구조와 document 내의 field(DB의 테이블 칼럼에 해당)의 속성을 정의하는 설정을 mapping이라고 한다. 
  • DB의 DDL의 개념과 유사하다.
  • Mapping은 기본적으로 JSON 형식을 띤다. 
  • GET [index 이름]/_setting의 결과 중 mappings 부분을 통해 mapping 정보를 확인할 수 있다. 

 

동적 Mapping, 명시적 Mapping

  • Elasticsearch에서는 사용자가 정의하지 않은 mapping에 대해서 정보를 추론하여 자동으로 mapping해주는 동적 Mapping을 제공한다.
  • 예를 들어, DB에서는 정의되지 않은 칼럼에 Insert를 하는 경우 에러가 뜨지만, Elasticsearch에서는 데이터 값을 토대로 형추론을 하여, 새로운 Field가 만들어진다. 
  • 동적 mapping은 자동으로 지정해 줘서 편리하다는 장점이 있지만, mapping 정보 중 대다수가 처음 정의된 이후 변경이 불가능하기 때문에, 사용자가 직접 mapping 정보를 정의하는 명시적 mapping 방법을 사용하는 게 좋다.

Field

  • Elasticsearch에서 각 Field에 지정할 수 있는 타입은 아래와 같다. 
타입 종류 설명
숫자 타입 정수 - long : 64 비트 정수
- integer : 32 비트 정수
- short : 16 비트 정수
- byte : 8 비트 정수
POST /number_example/_doc { "price": 19.99 }
소수 - double : 64 비트 소수
- float : 32 비트 소수
- half_float : 16 비트 소수
date 타입 - format을 지정하여 시간대로 변환 가능
- 내부에는 long 숫자로 색인됨
POST /date_example/_doc { "event_date": "2023-12-31" }
배열 -별도 타입 지정은 필요없지만, 배열의 각 원소들이 동일한 타입을 가져야함 POST /array_example/_doc { "tags": ["elasticsearch", "mapping", "example"] }
object 타입 - Field 안에 하위 Field 를 저장함 
- 실제 저장할 때는, 평탄화시켜서 key-value 형태로 저장
- object 타입은 하위 Field 간 관계를 유지하지 않음
POST /object_example/_doc { "address": { "city": "Seoul", "postcode": 12345 } }
nested 타입 - 중첩된 배열 구조를 다룰 때, 요소 간의 관계를 유지하도록 설계된 데이터 타입
- object 타입과 달리, 하위 Field 간 관계가 유지된다.  
POST /nested_example/_doc { "reviews": [ { "user": "Alice", "rating": 5, "comment": "Great product!" }, { "user": "Bob", "rating": 4, "comment": "Pretty good." } ] }
text 타입 - elasticsearch의 핵심 기능인 텍스트 검색을 위해 사용되는 타입
- text 타입에 데이터를 넣으면, analyzer(기본 값 standard analyzer)를 거쳐, 데이- 터를 역색인하여 검색이 가능하도록 함.
POST /text_example/_doc { "description": "Elasticsearch is a powerful search engine." }
keyword 타입 - 정확한 값을 검색하거나, 집계, 정렬, 필터링 등에 사용되기 위해 사용하는 타입
- text 타입과 달리 analyzer를 거치지 않고, normalizer를 거친 결과를 저장(지정 안해주면 문장 그대로 저장)
POST /keyword_example/_doc
{
  "status": "ACTIVE"
}

 

※ object 타입과 nested 타입 비교

  • object 타입과 nested 타입은 기본적으로 Field 안에 하위 Field를 저장할 수 있다는 점에서 비슷하지만, 요소 간의 관계를 유지하느냐 유지하지 않느냐에 따라 각각 nested 타입과 object 타입으로 분류된다. 
  • 예를 들어, "person" : [{"name" : "minsu" , "age": 30}, {"name" : "bora" , "age": 29}]라는 데이터가 각각 object 타입과 nested 타입으로 저장되었을 때, elasticseach 검색 조건을 "name":"bora"면서, "age":30으로 찾았을 때, nested 타입에서는 실제 저장의도와 같게 검색이 되지 않지만, object 타입으로 저장하였을 때는 검색이 된다.
  • 이것은 object 타입이 하위 Field 간 관계를 유지하지 않고, 각 하위 Field의 원소들을 List 형태로 평탄화 시켜 저장하기 때문이다.
  • 따라서, 하위 Field에 대한 복수 조건이 많이 존재할 경우에는 nested 타입으로 저장해야한다. (상대적으로 무겁기 때문에 남용해서는 안된다.)

 

※ text 타입과 keyword 타입 비교

  • 예를 들어, "나는 밥을 먹었다"라는 문장을 각각 text 타입과 keyword 타입에 넣으면, text 타입은 "나는", "밥을", "먹었다"로 역색인되어 저장될 것이고(analyzer마다 다르겠지만), keyword 타입은 "나는 밥을 먹었다"로 문장 그대로 저장될 것이다. 
특성 text 타입 keyword 타입
저장된 값 Token(analyer의 결과) 전체 
검색 가능성 부분 단어 매칭, 전체 텍스트 검색 가능 정확하게 일치해야 검색 가능
검색 query match, match_phrase term, terms
집계/정렬 불가능(집계/정렬을 위하면 메모리 기반 fielddata 캐시 이용→ OOM 가능성 농후) 가능 (디스크 기반 doc_values 캐시 이용)
사용 사례 단어 검색 고정 데이터 ex) 도시명 등 특성 정보

 

 

_source Field

  • 문서를 Elasticsearch에 저장하는 요청이 왔을 때, Elasticsearch에서는 문서의 원본 JSON 문서를 저장하는 데, 이 메타데이터 필드를 _source Filed라고 한다. 
  • _source는 indexing 후에도 원본 상태(JSON 형태)를 유지하고, 쿼리 결과로 반환될 데이터를 제공한다.  예를 들어, "BaKe"라는 단어를 text 타입으로 저장하였을 때, "BAKE"로 anlyzer 처리 후 저장되겠지만, 실제 문서를 검색하면, "BaKe"라는 원본 상태로 조회된다.
  • _source Field가 없으면, 데이터 자체를 조회하는 것이 불가하다.
  • 만약, Indexing된 결과는 저장해야 하지만, 원본 문서를 디스크 용량상이나, 보안상(ex : 비밀번호 복호화된 것만 저장) 검색되지 원치 않는다면, _source에 저장되지 않도록 할 수 있다. (mapping - _source - enabled를 false로 PUT 호출)

 

'ElasticSearch' 카테고리의 다른 글

Elasticsearch (2) 주요 용어 & Lucene  (0) 2024.11.26
ElasticSearch (1) 기본 개념  (25) 2024.11.18

+ Recent posts