Intro::
엘라스틱서치 실무 가이드 6장에 대한 정리본입니다.
한글 형태소 분석기 사용하기
Nori 형대소 분석기
설치방법
bin/elasticsearch-plugin install analysis-nori
JSON
복사
애널라이저 등록 및 테스트
PUT nori_analyzer
{
"settings": {
"analysis": {
"tokenizer": {
"nori_user_dict_tokenizer": {
"type": "nori_tokenizer",
"decompound_mode": "mixed",
"user_dictionary": "userdict_ko.txt"# /config/userdict_ko.txt
}
},
"analyzer": {
"nori_token_analyzer": {
"type": "custom",
"tokenizer": "nori_user_dict_tokenizer"
}
}
}
}
}
POST nori_analyzer/_analyze
{
"analyzer": "nori_token_analyzer",
"text": "잠실역"
}
JSON
복사
nori_part_of_speech 토큰 필터
품사 태그 세트와 일치하는 토큰을 찾아 제거하는 토큰 필터이다. 이를 이용하면 문서에 존재하는 모든 명사를 역색인으로 생성하는 것이 아니라 역색인될 명사를 선택적으로 고를 수 있다. 앞서 생성한 nori_analyzer 인덱스의 설정을 변경해보자.
POST nori_analyzer/_close
PUT nori_analyzer/_settings
{
"analysis": {
"analyzer": {
"nori_stoptags_analyzer": {
"tokenizer": "nori_tokenizer",
"filter": [
"nori_posfilter"
]
}
},
"filter": {
"nori_posfilter": {
"type": "nori_part_of_speech",
"stoptags": [
"E",
"IC",
"J",
"MAG",
"MAJ",
"MM",
"NA",
"NR",
"SC",
"SE",
"SF",
"SH",
"SL",
"SN",
"SP",
"SSC",
"SSO",
"SY",
"UNA",
"UNKNOWN",
"VA",
"VCN",
"VCP",
"VSV",
"VV",
"VX",
"XPN",
"XR",
"XSA",
"XSN",
"XSV"
]
}
}
}
}
POST nori_analyzer/_open
JSON
복사
nori_readingform 토큰 필터
한자를 한글로 변경하는 역할을 한다. 존재여부만 알아두자.
검색결과 하이라이트하기
데이터를 검색할 때 highlight 옵션을 이용해 하이라이트를 수행할 필드를 지정하면 검색 결과로 하이라이트된 데이터의 일부가 함께 리턴된다. 결과가 기본으로 <em>태그로 감싸서 반환되고 옵션을 통해 태그를 재정의 할 수 있다.
POST movie_highlighting/_search
{
"query": {
"match": {
"title": "harry"
}
},
"highlight": {
"pre_tags": [// 원하는 태그로 바꿔줄 수 있다.
"<strong>"
],
"post_tags": [
"</strong>"
],
"fields": {// 하이라이트
"title": {}
}
}
}
JSON
복사
스크립트를 이용해 동적으로 필드 추가
엘라스틱서치는 스크립트를 이용해 사용자가 특정 로직을 삽입하는 것이 가능하다. 이러한 방식을 스크립팅이라고 한다. 스크립팅을 이용하면 두 개 이상의 필드 스코어를 하나로 합하거나 계산된 스코어를 특정 수식으로 재계산하는 등의 작업이 가능해진다.
참고
엘라스틱서치에서 스크립팅을 사용하는 두 가지 방법이 있다.
1.
config 폴더에 스크립팅을 저장하는 방식: 스크립트 파일을 config 폴더에 저장한 다음, 이름을 지정해 코드에서 호출한다.
2.
in-requests 방식: 동적 스크립팅이라고 하며 API를 호출할 때 코드 내에서 스크립트를 직접 정의해서 사용한다.
일반적으로 동적 스크립팅 방식이 많이 사용된다. 동적 스크립팅 기능을 사용하려면 elasticsearch.yml 파일에 script.disable_dynamic: false 설정을 추가해야 한다.
엘라스틱서치는 기본적으로 업데이트를 허용하지 않는다. 재색인을 통해 설정한 _id의 문서를 삭제하고 다시 생성할 뿐이다. _update API는 내부적으로 스크립팅을 이용하고 있는 것이다.
ctx._source는 스크립트에서 제공하는 특수한 문법으로, 색인된 문서에 접근하기 위한 문법으로 이해하면 된다.
POST movie_script/_doc/1
{
"movieList": {
"Death_Wish": 5.5,
"About_Time": 7,
"Suits": 3.5
}
}
// 필드 추가
POST movie_script/_doc/1/_update
{
"script": "ctx._source.movieList.Black_Panther = 3.7"
}
// 필드 삭제
POST movie_script/_doc/1/_update
{
"script": "ctx._source.movieList.remove(\"Suits\")"
}
JSON
복사
검색 템플릿을 이용한 동적 쿼리 제공
검색 템플릿의 필드명과 파라미터를 사용해서 쿼리를 전송하고 템플릿에 제공한 파라미터로 실제 검색이 이뤄진다. 즉, 검색 템플릿을 사용하면 클라이언트의 코드가 단순해진다.
// _script API를 이용해 템플릿 생성
POST _scripts/movie_search_example_template
{
"script": {
"lang": "mustache",
"source": {
"query": {
"match": {
"movieNm": "{{movie_name}}"
}
}
}
}
}
// _script API를 이용해 검색
POST movie_template_test/_doc/_search/template
{
"id": "movie_search_example_template",
"params": {
"movie_name": "titanic"
}
}
JSON
복사
별칭을 이용해 항상 최신 인덱스 유지하기
인덱스를 생성할 때 별칭을 사용해 인덱스가 추가되거나 삭제될 경우 새로운 인덱스로 사용자 요청이 자연스럽게 이동하도록 유도한다. 이러한 방식을 통해 지금까지 사용 중인 인덱스가 새로운 인덱스로 변경되더라도 클라이언트는 그 사실을 눈치채지 못한다.
또한 인덱스의 별칭을 이용하면 두 개 이상의 인덱스를 검색해야 할 때 한 번의 요청만으로도 모두 검색되도록 만들기도 쉽다. 별칭은 멀티테넌시 형태(aIndex,bIndex/_doc/_search)를 하나의 인덱스처럼 만들어 클라이언트가 실제로 호출하는 인덱스를 내부에서만 알 수 있게 관리할 수 있다.
//_reindex API를 사용해 인덱스 생성
POST _reindex
{
"source": {
"index": "movie_search"
},
"dest": {
"index": "movie_info"
}
}
// _aliases를 통해 별칭 만들기
POST _aliases
{
"actions": [
{
"add": {
"index": "movie_search",
"alias": "movie"
}
},
{
"add": {
"index": "movie_info",
"alias": "movie"
}
}
]
}
JSON
복사
스냅샷을 이용한 백업과 복구
클러스터와 인덱스의 데이터가 커질수록 백업의 필요성도 커진다. 이러한 문제를 해결하기 위해 엘라스틱서치에서는 _snapshot API를 제공한다. 스냅샷 기능을 통해 개별 인덱스를 백업할 수도 있고 클러스터 전체를 스냅샷으로 만드는 것도 가능하다.
// 스냅샷을 저장할 디렉토리 생성
mkdir /home/snapshot/elastic/backup
// config/elasticsearch.yml 수정
path.repo: ["/home/snapshot/elastic/backup"]// 추가
// 레포지토리 생성
PUT _snapshot/movie_data_backup
{
"type": "fs",
"settings": {
"location": "home/snapsht/elastic/backup",
"compress": true
}
}
JSON
복사
레포지토리는 스냅숏들을 저장하는 논리적인 공간이라고 생각하면 되는데, 레포지토리는 물리적으로 설정된 디렉토리 내부에만 생성될 수 있다.
스냅샷 옵션
location | 스냅샷의 저장 경로를 설정한다. |
compress | 스냅샷 생성 시 압축을 수행한다. 이때 데이터는 압축되지 않으며 메타데이터만 압축 대상이 된다. |
chunk_size | 생성되는 파일을 특정 크기로 나눠서 생성할 수 있다. 기본적으로 스냅샷은 하나의 파일로 생성된다. |
max_restore_bytes_per_sec | 스냅샷 복원 시 속도를 설정한다. 기본적으로 초당 40MB의 속도를 낸다. |
max_snapshot_bytes_per_sec | 스냅샷 생성 시 속도를 설정한다. 기본적으로 초당 40MB의 속도를 낸다. |
readonly | 레포지토리를 읽기 전용으로 생성한다. |
레포지토리가 정상적으로 생성되면 스냅샷을 생성하면 된다. 기본적으로 스냅샷 대상이 되는 인덱스는 더 이상 변경이 없는 인덱스여야만 한다.
// 스냅샷 생성
PUT _snapshot/movie_data_backup/movie_snapshot_part1?wait_for_completion=true
{
"indices": "movie_search",
"ignore_unavailable": true,
"include_global_state": false
}
// 생성된 모든 스냅샷 정보 확인
GET _snapshot/movie_data_backup/_all
// 스냅샷을 이용해 복구하는 방법
POST _snapshot/movie_data_backup/movie_snapshot_part1/_restore
// 스냅샷 삭제
DELETE _snapshot/movie_data_backup/movie_snapshot_part1
JSON
복사
복구하고자 하는 인덱스가 이미 존재한다면 복구를 실패한다. 따라서 해당 인덱스를 삭제하고 복구해주면 된다.