매핑
- RDB에서 테이블을 생성할 때 컬럼의 이름, 데이터 타입을 정하는 것 처럼 매핑은 RDB의 스키마와 비슷한 역할을 한다.
- JSON 형태의 데이터를 루씬이 이해할 수 있도록 바꿔주는 작업
- 전문 검색과 대용량 데이터를 빠르게 실시간으로 검색할 수 있는 이유
다이내믹 매핑
JSON 도큐먼트의 데이터 타입에 맞춰 엘라스틱서치가 자동으로 인덱스 매핑을 해주는 것
{"age": 20}
→ 숫자 타입은 무조건 범위가 가장 넓은 long으로 매핑시켜 불필요한 메모리를 차지하게 만들 수 있으니 기억해두자.
→ GET index1/_mapping
mapping API 를 활용하여 인덱스 매핑값을 확인할 수 있다.
명시적인 매핑
인덱스 매핑을 직접 정의하는 것
// 인덱스 생성시 mappings 지정
PUT "인덱스명"
{
"mappings": {
"properties": {
"name": {"type": "text"}
"age": {"type": "short"}
...
}
}
}
인덱스를 생성할 때 mappings를 정의하거나 mapping API 를 이용해 매핑을 지정할 수 있다.
매핑 타입
매핑타입은 레퍼런스를 참고하자.
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
멀티 필드를 활용한 문자열 처리
엘라스틱서치 5.x 버전부터 문자열(string)타입이 텍스트(text)
와 키워드(keyword)
두 가지 타입으로 분리되어 있다. 이 두 가지 타입의 차이는 무엇일까? 또한 멀티 필드를 사용해 두 타입을 동시에 활용해보자
텍스트 타입
- 텍스트 타입은 일반적으로 문장을 저장하는 매핑타입으로 사용된다.
- 텍스트 타입으로 지정된 문자열은 분석기(analyzer)에 의해 토큰(token)으로 분리
- 토큰(token)들은 인덱싱되는데 이를 역인덱싱(inverted indexing)이라 함
- 역인덱스에 저장된 토큰들을 용어(term)이라고 함
아래 텍스트를 용어(term) 단위로 분석하면 어떻게 될까?
The world is full of suffering but it is also full of people overcoming it.
- [the, world, is, full, of ...] 와 같이 토큰으로 분리
- 이러한 용어(term)들은 역인덱스에 저장되어 전문 검색을 할 수 있게 한다.
- ‘overcoming’를 검색하면 전체 문장을 검색할 수 있음
- DBMS의 LIKE검색과 유사한데, LIKE 검색은 인덱싱이 되지 않아 엘라스틱처럼 많은 문서를 처리하기엔 무리가 있다.
실습
text_index 인덱스에 도큐먼트 인덱싱 후 인덱스 전문 쿼리를 날려 매칭결과를 확인해보자.
// 인덱싱
PUT text_index/_doc/1
{
"contents": "The world is full of suffering but it is also full of people overcoming it."
}
// 쿼리
GET text_index/_search
{
"query": {
"match": {
"contents": "world"
}
}
}
키워드 타입
- 키워드 타입은 카테고리나 사람 이름, 브랜드 등 규칙성이 있거나 유의미한 값들의 집합이다. (범주형 데이터에 주로 사용)
- 텍스트 타입과 다르게 분석기를 거치지 않고 문자열 전체가 하나의 용어로 인덱싱된다.
- ex. “hello world” → [hello, world] (x), [hello world] (o)
즉, 키워드 타입으로 “hello world”를 인덱싱 한 후 “hello”로 전문 검색 쿼리를 날린다면 일치하는 용어를 찾을 수 없다. “hello world”로 찾아야 한다.
멀티 필드
- 단일 필드 입력에 대해 여러 하위 필드를 정의하는 기능
- fields라는 매핑 파라미터가 사용된다. fields는 하나의 필드를 여러 용도로 사용할 수 있게 만들어 준다. (범주형 데이터로도 활용되면서 전문 검색이 가능한 필드)
실습
멀티 필드를 갖는 multi_index 인덱스 생성
PUT multi_index
{
"mappings": {
"properties": {
"message": {"type": "text"},
"contents": {
"type": "text",
"fields": {
"keyword": {"type": "keyword"}
}
}
}
}
}
- message, contents라는 2개의 필드를 갖는 multi_index 인덱스 생성
- contents필드는 멀티 타입으로 설정(텍스트 타입이면서, 키워드 타입)
텍스트 타입으로 검색
GET multi_index
{
"query": {
"match": {
"contents": "검색문자열"
}
}
}
키워드 타입으로 검색
GET multi_index
{
"query": {
"term": {
"contents.keyword": "검색문자열"
}
}
}
contents 하위에 keyword라는 하위 필드를 추가했으므로, contents.keyword로 접근해야한다.
인덱스 템플릿
- 동일한 복수의 인덱스를 만들 때 사용한다.
- 인덱스를 파티셔닝할때 사용된다. (동일한 설정의 인덱스를 생성)
템플릿 생성
템플릿 이름이 test_template인 인덱스 템플릿 생성
PUT _index_template/test_template
{
"index_patterns": ["test_*"],
"priority": 1,
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"name": {"type": "text"},
"age": {"type": "short"},
"gender": {"type": "keyword"}
}
}
}
}
- index_patterns : 인덱스 중에 인덱스 이름이 패턴과 매칭되는 경우 이 템플릿이 적용
- template : 새로 생성되는 인덱스에 적용되는 settings, mapping 같은 인덱스 설정을 정의
인덱스 템플릿 파라미터 참고
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html
템플릿 적용
템플릿 패턴에 맞는 인덱스를 만들어보자.
PUT test_index1/_doc/1
{
"name": "kang",
"age": 20,
"gender": "male"
}
template이 잘 적용된 것을 볼 수 있다.
if, template 매핑값과 다른 도큐먼트를 인덱싱하면 어떻게 될까? 바로 아래처럼 말이다..
PUT test_index2/_doc/1
{
"name": "kang",
"age": "알아서 뭐하게"
}
test_index2 는 test_template(test_*)템플릿이 적용지만, age의 매핑타입이 다르다.(문자형(텍스트)은 정수형으로 형변환이 불가하다.)
→ 400오류를 내뱉는다.
서적에서는 역인덱싱 관련해서 분석에 대한 내용도 나오지만, 딥하게 사용할 것 같지 않아 일단 생략한다. 언젠간 공부하지않을까 싶긴하다.
참고) 엘라스틱 스택 개발부터 운영까지
'프로그래밍 노트 > 인프라' 카테고리의 다른 글
[Logstash] 로그스태시란? 로그스태시 활용기 (0) | 2022.08.16 |
---|---|
[엘라스틱 서치] 인덱스와 도큐먼트란 무엇인가?? (0) | 2022.01.03 |
[엘라스틱 스택] 맥북 실습 환경 구성 (0) | 2021.12.30 |
[엘라스틱 스택] 엘라스틱 스택 찍먹하기 (0) | 2021.12.23 |
[kafka] 카프카 프로듀서 주요 옵션 및 전송방법 (0) | 2021.08.09 |