-
[ElasticSearch 엘라스틱서치] 멀티 필드 맵핑, 정렬과 검색을 동시에[IT] 공부하는 개발자/Open Source 2019. 8. 21. 00:45
엘라스틱서치, Mapping?
엘라스틱서치 안에서 맵핑이란, 사용될 필드들의 타입(자료형)을 사전에 정의해주는 것이다. 관계형 데이터베이스로 비유하자면 스키마 정의와 같다. 텍스트 타입 이외에도 다양한 숫자 타입, 날짜 타입, 위치 데이터 등으로 정의할 수 있으며 디테일한 커스텀 설정이 가능하다. 이 포스팅은 맵핑안에서 "fields" 파라미터를 이용하여, 한 필드가 다양한 특성을 동시에 가질 수 있도록 커스텀 맵핑하는 법에 대해 설명한다.
1. 맵핑 기본문법 SYNTAX
# MAPPING
PUT /my-index { "mappings": { "properties": { "age": { "type": "integer" }, "email": { "type": "keyword" }, "name": { "type": "text" } } } }
my-index 라는 인덱스에 사용될 필드들을 맵핑하였다. age 필드는 integer 타입, email 필드는 keyword 타입, name 필드는 text를 가지도록 맵핑한다.
# UPDATE
PUT /my-index/_mapping { "properties": { "employee-id": { "type": "keyword", "index": false } } }
기존의 index에 새로운 필드 맵핑을 추가할수도 있다. employee-id 라는 keyword 타입의 필드을 새로 정의하였다.
단, 이미 정의된 필드의 경우, 타입 변경은 불가능하고 "fields" (이 포스팅에서 설명할 멀티 필드 기능) / "ignore_above" 파라미터를 수정하는 경우에 한해서만 허용된다.
# VIEW
GET /my-index/_mapping
정의된 맵핑을 조회하는 쿼리이다. 예상되는 리턴은 아래와 같다.
{ "my-index" : { "mappings" : { "properties" : { "age" : { "type" : "integer" }, "email" : { "type" : "keyword" }, "employee-id" : { "type" : "keyword", "index" : false }, "name" : { "type" : "text" } } } } }
2. 필드 데이터 타입
TYPE 구분 타입 단순형 (SIMPLE TYPE) TEXT: 풀 텍스트 (상품 설명, 질문 답변)
KEYWORD: 인덱스화되어있는 키워드타입의 데이터 (예시: 이메일주소, 우편번호)
DATE: 날짜형, LONG: 숫자형, DOUBLE: 숫자형, BOOLEAN: 바이너리, IP계급형 (HIERARCHICAL TYPE) OBJECT, NESTED 특수형 (SPECIALISED TYPE) GEO_POINT, GEO_SHAPE, COMPLETION 다양한 타입으로 정의할 수 있다 (참조)
3. 멀티 필드 맵핑
멀티 필드 맵핑의 활용법
- 특정 필드에 풀 텍스트 검색 & 정렬 등을 동시에 사용하고 싶을 때
- 특정 필드에 여러 가지 분석기(Analyzer)를 적용하고 싶을 때
멀티 필드 맵핑은, 엘라스틱 서치 안에서 동일한 필드를 다른 용도로 사용하고자 할 때에 무척 유용하다. 예를 들어 '상품 이름' 이라는 항목에 analyzer도 사용하고 싶고, 동시에 클러스터링이나 정렬도 사용하고 싶다면 난감할 수 있다. 키워드 필드 데이터에는 analyzer를 사용할 수 없고, text 형 데이터는 정렬기능이 지원되지 않기 때문이다. 두 가지 특성을 모두 사용할 수 없을까? 이 경우는 "fields" 파라미터를 추가해, 멀티 맵핑을 하면 된다.
멀티 필드 맵핑 쿼리
PUT my_index { "mappings": { "properties": { "city": { "type": "text", "analyzer": "english" "fields": { "raw": { "type": "keyword" "normalizer": "custom_normalizer" } } } } } }
city 라는 이름의 데이터 타입을 정의하였다. 기본 타입은 text 타입에, english 분석기를 사용하도록 했다. 그리고 fields 파라미터로 "raw" 라는 자식을 따로 정의하였다. 자식 필드는 keyword 타입에, custom_normalizer 라는 노멀라이저를 사용한다. (*분석기가 텍스트 타입에만 사용가능한 반면, 노멀라이저는 키워드 타입에 사용할 수 있고, 성능은 거의 동일한데 노멀라이즈는 단일화 토큰을 생성한다. 자세한 것은 링크 참조)
맵핑 후 테스트 데이터 삽입
PUT my_index/_doc/1 { "city": "New York" } PUT my_index/_doc/2 { "city": "York" }
city 필드에 "New York", "York"라는 데이터 2개를 삽입하였다.
검색 쿼리
GET my_index/_search { "query": { "match": { "city": "york" } }, "sort": { "city.raw": "asc" }, "aggs": { "Cities": { "terms": { "field": "city.raw" } } } }
city는 멀티 필드 맵핑에 의해서, 분석기가 적용된 text 타입과 노멀라이저가 적용된 keyword 타입 양 쪽 모두 가지므로 검색, 정렬, 클러스터링에 동시에 사용될 수 있다. 검색쿼리의 타겟은 "city" 필드가(text 타입) 타겟이 되고, 정렬과 클러스터링 쿼리는 "city.raw"(keyword 타입) 필드가 타겟이 된다.
기타
- 하위 노드의 명칭은 편의에 따라 raw 이외의 이름으로 변경할수도 있다.
'[IT] 공부하는 개발자 > Open Source' 카테고리의 다른 글
logstash 'unknown setting *** for jdbc' 에러 메시지 (0) 2020.12.07 [Kafka] 터미널에서 카프카 토픽 생성, 발행, 컨슘하기 (0) 2020.05.07 [엘라스틱서치] ElasticSearch & 키바나 시큐리티 기능 구현 (0) 2019.09.08 [도커 + 엘라스틱서치] Docker로 ElasticSearch ELK 스택 디플로이 (0) 2019.08.26 NOOK Glowlight plus 누크뿔 크레마 설치하기 [2019년판] (윈도우/맥OS) (2) 2019.08.12