태그 : solr

2009/03/27   Lucene 한글 복합명사 처리 [2]

Lucene 한글 복합명사 처리

Lucene 에서 한글 복합명사를 처리할 때 발생하는 난감한 상황입니다. 한글 처리는 korlucene 을 이용했습니다.
복합명사로 검색할 때와 명사를 띄어 써서 검색할 때 검색 결과가 다르게 나타납니다.
그 이유를 설명드리겠습니다.

name 이란 필드에서 "만성간염" 이란 단어를 검색한다고 가정하겠습니다. 
현재는 "만성간염"을 KoreanFilter 로 처리하면,

term position1
term text간염
만성간염
만성

처럼 나옵니다. term position 이 동일한 것들은 유의어 처럼 처리를 합니다.
따라서, 최종적으로 생성되는 Query 는 BooleanQuery 이고, 이를 String 형태로 보면

name:간염 name:만성간염 name:만성

이 됩니다. 따라서, "간염", "만성간염", "만성" 이 세 개의 단어 중 하나라도 들어있는 문서가 검색이 됩니다.
즉, OR 검색이 되는 것이죠. 이것은 solr 에서

<solrQueryParser defaultOperator="AND"/>

와 같이 설정을 하였더라도 유의어로 보기 때문에 위와 같이 Query 가 생성이 됩니다.

그 다음 "만성 간염"으로 띄워서 쓰면 어떻게 될까요? solr analysis 에서 보면 아래와 같습니다.

term position12
term text만성간염

Query 를 생성할 때는 "만성", "간염"을 먼저 분리한 후, name 필드를 각각 적용하게 됩니다.
그래서 defaultOperator 가 AND 일 때

+name:만성 +name:간염

으로 Query 가 생성됩니다. "만성"과 "간염"이 동시에 들어있는 문서가 검색 결과로 나옵니다.
defaultOperator 가 OR 이면,

name:만성 name:간염

으로 Query 가 생성이 되고, "만성" 또는 "간염" 이 들어있는 문서가 검색됩니다.

만약에 KoreanFilter 를 수정해서 term position 을 달리하면 어떻게 될까요? 실제로 KoreanFilter 를 수정을 해서 실험을 해보았습니다.

term position12
term text만성간염
만성간염

하나의 token 이 term position 이 다른 여러 개의 token 들로 쪼개질 때는
BooleanQuery 가 아닌, PhraseQuery 가 생성됩니다. (위 경우엔 엄밀하게 MultiPhraseQuery 입니다.)
즉, 최종 Query 의 스트링은

name:"만성 (간염 만성간염)"

으로 생성이 됩니다. 엉뚱하게도 "만성 (간염 만성간염)"으로  exact 매칭을 시도하기 때문에,
이런 경우엔 "만성간염"이 당연히 결과에 나오지 않습니다.

만약, "만성간염"을 

term position12
term text만성간염

이렇게 필터링이 되게 했을 때도 PhraseQuery 가 생성이 되고,

name:"만성 간염"

으로 검색을 하기 때문에 "만성 간염"으로 exact 매칭을 하여 "만성간염"은 검색되지 않습니다.

조금 내용이 헛갈리실 수도 있는데, 결론적으로 말씀드리면, lucene 의 기본 QueryParser 클래스를 이용해서는 복합명사에 대해 AND 검색이 안 된다는 점입니다.
"만성간염"을 입력했을 때, "만성간염", "만성 간염" 뿐만 아니라, "B형간염", "A형간염", "간염" 등의 결과가 같이 나올 수 밖에 없습니다.

KoreanFilter 를 사용하지 않았을 때는 반대로 "만성간염"을 입력해서 "만성 간염"을 찾을 수 없게 됩니다.

아무래도 복합명사 AND 검색이 가능하게 하려면, query parser 를 별도로 하나 만들어야 할 거 같습니다.
by 단상 | 2009/03/27 23:10 | Lucene / Solr | 트랙백 | 덧글(2)
<< 이전 페이지 다음 페이지 >>