2015년 8월 13일 목요일

SOLR와 Elasticsearch에서 MeCab을 사용할 때 특수문자 허용 검색하기

Apache SOLR 또는 Elasticsearch에서 한글 형태소 분석기로 Mecab Ko를 사용할 때 천원 단위 구분 또는 소수점이 포함된 숫자 타입을 검색할 때 특수문자를  SY(SYMBOL)로 태깅하고 있어서 .와 ,를 숫자와 결합하여 색인 또는 검색하는 방법을 찾지 못했다. (불가능한 것일지도...)

이번 포스팅에서는 상기의 문제점을 해결하려고 시도한 첫번째 방법과 최근에 수정한 방법을 작성했다.

문제의 검색키워드 : 1.5m 케이블

mecab 분석결과 :
1    SN,*,*,*,*,*,*,*
.     SY,*,*,*,*,*,*,*
5    SN,*,*,*,*,*,*,*
m   SL,*,*,*,*,*,*,*
케   XSV+EC,*,F,케,Inflect,XSV,EC,하/XSV/*+게/EC/*
케이블   NNG,*,T,케이블,*,*,*,*

검색/색인결과 : 
1 / 5 / m / 케이블

이렇게 색인/검색이 되기 때문에 정확하게 '1.5m 케이블' 외에 원하지 않은 결과가 상당 수 포함되었으며,
또한 마침표가 포함된 동의어를 등록할 수가 없었다.
예) 21.5 => 22


[Mecab Ko를 수정하지 않고 처리하는 방법]

PatternReplaceCharFilter를 사용해서 처리한다.

1) Solr : solr.PatternReplaceCharFilterFactory
2) Elasticsearch : Pattern Replace Char Filter 

상기의 필터를 적용하면 1.5에서 .을 제거하고 분리된 음절을 결합한다.

Solr에 적용 예)
<fieldType name="text_ko" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="org.bitbucket.eunjeon.mecab_ko_lucene_analyzer.StandardTokenizerFactory" compoundNounMinLength="3" />
    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="[\.]" replacement=""/>
  </analyzer>
</fieldType>
  

결과) 1.5m 케이블 -> 15 / m / 케이블

문제점) 당연한 결과지만 15m 케이블도 같이 검색 결과로 노출된다.


[Mecab Ko를 수정해서 처리하는 방법]


[STEP 1]
mecab-ko-dic-x.x.x의 char.def에서 ASCII Code 0X2E ( . ) 와 0X2C ( , )를 SYMBOL에서 제외한다.
# ASCII
# 0x0021..0x002F SYMBOL
0x0021..0x002B SYMBOL
0x002D SYMBOL
0x002F SYMBOL
0x0030..0x0039 NUMERIC
0x003A..0x0040 SYMBOL
0x0041..0x005A ALPHA
0x005B SYMBOL
0x005D..0x0060 SYMBOL
0x0061..0x007A ALPHA
0x007B..0x007E SYMBOL

[STEP 2]
$ cd mecab-ko-dic-XX
$ make clean
$ ./configure
$ make
$ su make install

[STEP 3]
$ cd /usr/local/bin
$ ./mecab

1.5m 케이블

1    SN,*,*,*,*,*,*,*
.     SF,*,*,*,*,*,*,*
5    SN,*,*,*,*,*,*,*
m   SL,*,*,*,*,*,*,*
케   XSV+EC,*,F,케,Inflect,XSV,EC,하/XSV/*+게/EC/*
케이블   NNG,*,T,케이블,*,*,*,*

1,500원

1    SN,*,*,*,*,*,*,*
,    SC,*,*,*,*,*,*,*
500    SN,*,*,*,*,*,*,*
원    NNBC,*,T,원,*,*,*,*

[STEP 4]
mecab-ko-lucene-analyzer-0.17.x의 StandardPosAppender.java에서 결합규칙 추가
// 숫자(SN), 기호(SF/SC)는 모두 연결
appendableSet.add(new Appendable(PosId.SN, PosId.SC));   
appendableSet.add(new Appendable(PosId.SC, PosId.SN));
appendableSet.add(new Appendable(PosId.SN, PosId.SF));
appendableSet.add(new Appendable(PosId.SF, PosId.SN));

[STEP 5]
Maven Build

[STEP 6]
색인/검색 분석 결과 확인

1) Elasticsearch
curl -XGET 'http://127.0.0.1:9200/eunjeon/_analyze?analyzer=korean_query&pretty=true' -d '1.5m케이블'
{
  "tokens" : [ {
    "token" : "1.5",
    "start_offset" : 0,
    "end_offset" : 3,
    "type" : "EOJEOL",
    "position" : 1
  }, {
    "token" : "m",
    "start_offset" : 3,
    "end_offset" : 4,
    "type" : "SL",
    "position" : 2
  }, {
    "token" : "케이블",
    "start_offset" : 4,
    "end_offset" : 7,
    "type" : "NNG",
    "position" : 3
  } ]
}

2) Solr

댓글 없음:

댓글 쓰기