참고 서적 엘라스틱서치 실무 가이드 - 거의 여기 다 있는 내용임, 이거 저작권(http://www.copy112.or.kr)에 걸릴거 같음. 너무 많은 부분을 가져 왔음
0. 한국어 텍스트 나누기
1 Nori 형태소 분석기
2 설치
1) 플러그인 설치
윈도우 D:\elasticsearch-6.6.1\bin>elasticsearch-plugin.bat install analysis-nori -> Downloading analysis-nori from elastic [=================================================] 100%?? -> Installed analysis-nori D:\elasticsearch-6.6.1\bin> 리눅스 D:\elasticsearch-6.6.1\bin>elasticsearch-plugin install analysis-nori |
3 분석기
1) 문자 필터
2) 토큰 나이즈
3) 토큰 필터
4 nori_tokenizer 토크 나이저
1) decompound_mode
토크나이저가 복합 명사를 처리하는 방식을 결정, 복합 명사가 있을 경우 단어를 어떻게 쪼갤지를 결정, 단어를 쪼개는 방법은 아래 세가지 중에서 설정
(복합어는 하나의 실질 형태소에 접사가 붙거나 두개 이상의 실질 형태소가 결합된 말, 둘 이상의 말이 결합된 명사)
파라미터 값 | 설명 | 예제 |
---|---|---|
none | 복합 명사로 분리하지 않음 | 지름길, 눈물 |
discard | 복합 명사로 분리하고 원본 데이터는 삭제 | 잠실역 => [ 잠실, 역 ] |
mixed | 복합 명사로 분리하고 원본 데이터는 유지 | 잠실역 => [ 잠실, 역, 잠실역 ] |
2) user_dictionary
nori plugin 설치 후에 재부팅 후에 해야 됨 PUT nori_analyzer { "settings": { "index": { "analysis" : { "tokenizer" : { "nori_user_dict_tokenizer" : { "type" : "nori_tokenizer", "decompound_mode": "mixed", "user_dictionary" : "userdict_ko.txt" } }, "analyzer" : { "nori_token_analyzer" : { "type" : "custom", "tokenizer": "nori_user_dict_tokenizer" } } } } } } |
테스트 POST nori_analyzer/_analyze { "analyzer": "nori_token_analyzer", "text" : "부슬비" } -------------------------------- 실행 결과 --------------------------------- { "tokens" : [ { "token" : "부슬비", "start_offset" : 0, "end_offset" : 3, "type" : "word", "position" : 0, "positionLength" : 2 }, { "token" : "부슬", "start_offset" : 0, "end_offset" : 2, "type" : "word", "position" : 0 }, { "token" : "비", "start_offset" : 2, "end_offset" : 3, "type" : "word", "position" : 1 } ] } |
5 토큰 필터
1) nori_part_of_speech 토큰 필터
예) 명사를 제외한 모든 형태소를 제거하는 예제
인덱스를 close 하고 설정을 변경
POST nori_analyzer/_close
PUT nori_analyzer/_settings { "index" : { "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 |
POST nori_analyzer/_analyze { "analyzer": "nori_stoptags_analyzer", "text" : "거울아 거울아 세상에서 누가 제일 잘 생겼냐? 정대형!" } { "tokens" : [ { "token" : "거울", "start_offset" : 0, "end_offset" : 2, "type" : "word", "position" : 0 }, { "token" : "거울", "start_offset" : 4, "end_offset" : 6, "type" : "word", "position" : 2 }, { "token" : "세상", "start_offset" : 8, "end_offset" : 10, "type" : "word", "position" : 4 }, { "token" : "누구", "start_offset" : 13, "end_offset" : 15, "type" : "word", "position" : 6 }, { "token" : "정대", "start_offset" : 26, "end_offset" : 28, "type" : "word", "position" : 13 } ] } 다른 예제 POST nori_analyzer/_analyze { "analyzer": "nori_stoptags_analyzer", "text" : "정말 너무 너무 맛있다." } 아래와 같이 하나도 토큰이 없음 { "tokens" : [ ] } |
stoptags 설명
2) nori_readingform 토큰 필터
PUT nori_readingform { "settings": { "index" : { "analysis" : { "ananlyzer" : { "nori_readingform_analyzer" : { "tokenizer" : "nori_tokenizer", "filter" : ["nori_readingform"] } } } } } } 위에 인덱스에 POST nori_readingform/_analyze { "analyzer": "nori_readingform_analyzer", "text" : "日本" } 이걸 실행하면 오류가 났다. 오타도 없는데... 뭐가 문제인지... ㅠ.ㅠ { "error": { "root_cause": [ { "type": "remote_transport_exception", "reason": "[mVjXfLn][127.0.0.1:9300][indices:admin/analyze[s]]" } ], "type": "illegal_argument_exception", "reason": "failed to find analyzer [nori_readingform_analyzer]" }, "status": 400 } 그래서 다시 만들어 봤음 PUT korean_nori_readingform { "settings": { "index" : { "analysis":{ "analyzer":{ "korean_nori_analyzer":{ "type":"custom", "tokenizer":"nori_tokenizer", "filter":[ "nori_readingform" ] } } } } } } POST korean_nori_readingform/_analyze { "analyzer":"korean_nori_analyzer", "text":"日本에 저와 함께 가시지 않겠습니까?" } 결과가 잘 나왔다 { "tokens" : [ { "token" : "일본", "start_offset" : 0, "end_offset" : 2, "type" : "word", "position" : 0 }, { "token" : "에", "start_offset" : 2, "end_offset" : 3, "type" : "word", "position" : 1 }, { "token" : "제", "start_offset" : 4, "end_offset" : 5, "type" : "word", "position" : 2 }, { "token" : "와", "start_offset" : 5, "end_offset" : 6, "type" : "word", "position" : 3 }, { "token" : "함께", "start_offset" : 7, "end_offset" : 9, "type" : "word", "position" : 4 }, { "token" : "가시", "start_offset" : 10, "end_offset" : 12, "type" : "word", "position" : 5 }, { "token" : "지", "start_offset" : 12, "end_offset" : 13, "type" : "word", "position" : 6 }, { "token" : "않", "start_offset" : 14, "end_offset" : 15, "type" : "word", "position" : 7 }, { "token" : "겠", "start_offset" : 15, "end_offset" : 16, "type" : "word", "position" : 8 }, { "token" : "습니까", "start_offset" : 16, "end_offset" : 19, "type" : "word", "position" : 9 } ] } |
한글 형태소 분석기로 Nori를 사용하려면 다음과 같이 설정하면 된다고 합니다.... 책에서...
PUT nori_full_analyzer { "mappings": { "_doc" : { "properties": { "desription" : { "type" : "text", "analyzer" : "korean_analyzer" } } } }, "settings": { "index" : { "analysis" : { "analyzer" : { "korean_analyzer" : { "filter" : [ "pos_filter_speech", "nori_readingform", "lowercase" ], "tokenizer" : "nori_tokenizer" } }, "filter": { "pos_filter_speech" : { "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_full_analyzer/_analyze { "analyzer": "korean_analyzer", "text" : "나는 왕이다. 大王" } 잘 된다. |
끝..................... 이거 발표만 하고 지워야 할거 같음.... 책을 너무 베껴서... 잡혀 갈거 같음