본문 바로가기

Lucene

[about Lucene] 루씬으로 검색엔진 개발하기 Sort와 CustomScore

검색결과에 대한 기본적인 정렬은
TF-IDF 의한 유사도 점수입니다. 하지만 검색결과를
우리의 입맛대로 조절해야 하는 경우가 있습니다. 이를 위해서 루씬에서는
Sort클래스와 그외 몇가지 확장 가능한 API 제공합니다.

여기서는 우선 Sort클래스의 기본적인 사용법을 확인해보겠습니다.

 

SortTest.java

보시면 2 필드에 대해서 정렬을 하고 있습니다.
Sort클래스의 사용은 우선 정렬에 사용 SortField 생성하고 이를 사용해
Sort클래스의 인스턴스를 만들어서 IndexSearcher 통해 검색을 합니다.

여태까지
IndexSearcher로부터 받아오는 결과 클래스가 TopDocs였지만
필드 정렬을 사용 때는 TopFieldDocs라는 클래스로 결과가 받아집니다.
외에도 Collector 사용하여 결과를 받아 수도 있습니다.

Field 의한 정렬이 되기 위해서는 해당 필드가
NOT_ANALYZED 색인이 되어 있어야 합니다. 그래서 예제 같은 경우
검색을 위한 title 외에 title2라는 필드를 추가로 생성하고 정렬에 사용하고 있습니다.

하나는 SortField 설정하는 SortType 색인시 Field 설정한 타입이 같아야 합니다.

만약 예제에서 sortByField 메서드의 SortField 타입을 INT형으로 바꾼다면
예제는 에러가 발생합니다.

위의 예제가 기본적으로 루씬에서 제공되는 정렬 방법입니다.
다만 정렬이라는 것이 전체 데이터셋을 구한 상태에서의 작업이기 때문에 결과셋이 많을 수록
(즉, 정렬해야 하는 대상 문서가 많을수록...) 속도나 리소스 사용 측면에서 성능이 떨어지는 경우가
있습니다.

이를 조금 다르게 생각해보면
전체 결과를 구해놓고 정렬하는 것이 아니라 TF-IDF점수를 활용하여 정렬하는 것 처럼
대상 문서를 가져 올 때 정렬을 시키면 어떨까? 라는 생각을 해 볼 수 있습니다. 

"짐승"이란 닉네임으로 활동하고 계시는 진성주님의 블로그를 참고해보세요.
(http://blog.softwaregeeks.org/archives/89)

보시면 CustomScoreQuery 클래스를 활용하여 위에서 얘기되었던 고민을 해결하고 있습니다.
즉, 검색 대상 문서를 찾으면서 정렬하는 방식이지요...

이 부분에 대한 설명은 예전에 제가 CustomScoreQuery 사용하여 정렬에 대한 예제와 설명을
작성했던 글이 있습니다.

이 부분은 그 포스트들의 링크로 대신하려고 합니다.

루씬에서뿐만이 아니라 어느 검색엔진에서도 결과Set굉장히 클 때의 정렬은 고민거리가 됩니다.
여러분께서도 루씬을 사용하시면서 문서의 수가 점점 커질 수록 이 부분에 대한 고민이
되실 것 입니다. 그때 하나의 해결책으로써의 방법이 될 수도 있으니 꼭 한번 읽어보시기를 권해드립니다.


이 포스트까지 하면 루씬을 활용하여 검색엔진을 만들어보기 위한
기본적인 내용들은 다 작성을 한 것 같습니다

사실 Analyzer의 구현이 가장 어려운 부분이고 끊임없이 손을대고 사전을 다듬어야 하기 때문에
가장 번거로운 부분이기도 합니다. Analyzer를 제외한 나머지 부분들은 잘 만들어진 API를 잘 사용하는 것이기 때문에
직접 사용하시면서 숙달하시는 방법이 가장 좋은 방법이구요..

이후에는 Replication에 대한 내용과
그외 생각나는 Tip과 경험담의 위주로 내용을 작성해나가려고 합니다.

실제로 하나의 완성된 검색엔진 개발 과정을 보여드리려고 했는데
내년 정도에 한번 진행을 해보게 될 것 같네요.

about Lucene 카테고리 외에 Lucene 카테고리에도 이미 경험했던 내용들에 대한
많은 내용들이 있으니 참고해주세요.
 
예제는
https://github.com/need4spd/aboutLucene
에서 받으 실 수 있습니다. 

CustomScoreQuery에 대한 예제 소스는
패키지 com.tistory.devyongsik.customscore 밑에 있습니다.