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 |