본문 바로가기

Lucene

[about Lucene] 루씬으로 검색엔진 개발하기 - Analyzer (3) - 이제 정말로 구현을 해 볼 시간입니다. 실제의 구현은 TDD의 형태를 따라가도록 하겠습니다. 기본적으로 우리가 원하는 결과를 테스트케이스로 만들어 놓고 실제 구현을하여 테스트케이스를 통과하는 형태로 개발을 하겠습니다. Analyzer가 하나의 Tokenizer 그리고 여러개의 TokenFilter로 이루어져 있다고 말씀드렸는데요, 하나하나에 대해서 테스트 케이스를 먼저 살펴보고 최종적으로 완성된 Analyzer의 테스트 케이스를 확인해보도록 하겠습니다. 들어가기전에 앞 포스트에서 Tokenizer에서 키워드를 추출하면서 색인과 검색에 필요한 Attribute들을 설정하고 이 Attribute들이 모여있는 클래스를 AttributeSource라고 말씀드렸었는데요, TokenFilter에서는 이 Attrib.. 더보기
[about Lucene] 루씬으로 검색엔진 개발하기 - Analyzer (2) - 그러면 이제 루씬에서의 Analyzer에 대해서 살펴보도록 하겠습니다. 이제부터 정말 작성하기가 조심스러워지네요... 저도 루씬을 잘 이해하고 있는 상태는 아니라서.... ㅎㅎ 더군다나 제가 공부하며 만들었던 루씬 버전이 2.4 정도 버전인데 현재 3.3 버전은 기본적인 개념은 비슷하겠지만 내부적은 구현 방식은 완전히 바뀌었더라구요... 앞으로 내부적인 루씬 소스에대한 설명보다는 주로 사용법/커스터마이즈 방법을 소개해드리게 될 것 같습니다. 우선 Analyzer가 어떻게 사용되는지 보도록 하겠습니다. AnalyzerUsageSampleTest.java 우선 분석 할 문장을 StringReader로 생성하고, 이 문장을 분석 할 Analyzer를 생성합니다. 여기서는 WhitespaceAnalyzer를 이.. 더보기
[about Lucene] 루씬으로 검색엔진 개발하기 - Analyzer (1) - 앞에 데모 프로그램을 보셔서 아시겠지만 검색이라는 하나의 작업을 위해서는 크게 색인과 검색이라는 2가지 프로세스를 거쳐야 합니다. 이중 색인과 검색에 모두 관여하는 것이 하나 있는데 그것이 바로 키워드 추출.. 즉, 흔히 이야기하는(하지만 너무나 어려운) 형태소분석입니다. (이후에는 키워드 추출이라고 하도록 하겠습니다.) 잠깐 루씬을 떠나서 검색이론에 대해서 이야기 해 보겠습니다. 흔히 검색에서 이야기하는 색인 파일은 대부분 "역색인(Inverted Index)" 구조로 되어있습니다. 이게 어떤 구조인가하면.... 책의 맨 뒤 부록에 나오는 "단어"를 기준으로 페이지를 나열한 형태의 색인 구조라고 보시면 됩니다. 나이키 - Doc1, Doc2, Doc3 운동화 - Doc1, Doc5 청바지 - Doc6.. 더보기
[about Lucene] 루씬으로 검색엔진 개발하기 - Demo - 루씬이란 무엇인가? 에서 부터 시작을 해봐야 할 것 같습니다. 루씬은 full text 검색엔진을 만들 수 있는 라이브러리를 제공합니다. 검색엔진이라고 하면 키워드분석 / 색인 / 검색의 과정을 수행하는 것으로 크게 나눠 볼 수 있겠는데, 이런 과정들을 실제로 구현 할 수 있는 API를 제공합니다. 우선 루씬을 사용해서 색인과 검색이 어떠한 방식으로 이루어지는지 예제를 보는 것이 가장 손쉽게 루씬에 대해서 알아 볼 수 있는 방법이 될 것 같습니다. 이 예제들은 파일들로부터 내용을 색인하고 그 색인 파일을 사용하여 키워드로 내용을 검색하는 예제입니다. 굉장히 간단한 예제이지만 사실 검색엔진을 구현하는데 있어서 가장 필수적인 내용들은 거의 다 들어가 있다고 보셔도 됩니다. 그만큼 이 루씬이라는 라이브러리가 .. 더보기
[about Lucene] 루씬으로 검색엔진 개발하기 -Prologue- 최근들어 루씬에 대해서 개인적으로 혹은 블로그등을 통해서 문의를 해주시는 분들이 많이 늘었습니다. 검색에 대한 관심이 커진 이유인지 잘 모르겠네요~ 원래 재미있고 어려운 분야긴해서.. 예전에 GS에 있을 때 루씬인액션 번역본 (1.4 기준) 책 한권을 들고 루씬으로 검색엔진을 만들어 본다고 한번 개발을 했던 (이게 벌써.. 3년 4년전이네요...) 경험과 그때 공부한 내용들을 이곳에 정리하긴 하였는데 사실 Case by Case로 작성한 포스트가 많아 처음 루씬을 접하시는 분들은 보시기가 쉽지 않으셨던 것 같습니다. 그 당시 나름 Solr에 대응한다고 Moon(ㅋㅋ)이라는 이름으로 프로젝트를 진행하였었고 한번 테스트 해볼만한 상태까지는 개발을 했었지만 외부 사정에 의해서 거기서 진행을 접을 수 밖에 없었.. 더보기
[Lucene] Numeric 필드의 사용과 주의점 빠른 정렬을 위해서 Number의 값을 갖는 필드에 대해서 Numeric 필드를 사용하도록 이번에 로그 분석 프로그램을 개발하면서수정하였다. 아.. 근데 이걸로 이렇게 시간을 끌줄이야...ㅠㅠ 루씬은 String만으로도 색인이 가능하지만 숫자 필드에 대해서는 특별한 필드 타입을 지원하는데 그것이 바로 NumericField 필드이다. NumericField의 사용 위와 같은 방식으로 일반적인 필드 생성과는 조금 다른 방식으로 작동을 하게 된다. 위와 같이 필드를 설정하면 아래와 같은 쿼리식이 가능하다. 주의 할 점은 색인 할 때 사용한 Numberic 필드의 타입과 RangeQuery에 셋팅되는 타입이 같아야 한다. NumericField의 구간 검색 쿼리 생성 다만 주의 할 점은 필드에 들어가는 값의 .. 더보기
[Lucene] MultiSearcher의 사용 (3.0.3 기준) -2- IndexSearcher는 Index의 변경 내용을 그 상태로는 인지 하지 못 합니다. 주로 IndexWriter에 의해서 추가적인 색인이 되거나 IndexReader에 의한 삭제등이 될텐데요.. 제가 구현하고 있는 프로그램도 하루에 한번 로그를 분석 후 색인을 추가하기 때문에 색인 파일 변경에 대한 감지를 하여 이를 처리 할 수 있어야 했습니다. MultiSearcher를 사용했기 때문에 각 Searcher들이 바라보고 있는 Index파일들을 모두 체크하여 인덱스 파일이 변경되었을 경우 Index파일을 다시 열어서 IndexSearcher를 다시 생성하는 방법을 사용하기로 하였습니다. 각 Searcher별로 가지고 있는 IndexReader를 MultiSearcher로 부터는 직접적으로 얻을 수 없었기.. 더보기
[Lucene] MultiSearcher의 사용 (3.0.3 기준). -1- 이걸 쓴다쓴다 하면서 이제서야 써보네요.... 회사에서 간단하게 조회 할 수 있는 프로그램을 만들면서 루씬을 사용하여 데이터를 저장하고 조회 할 수 있도록 하였습니다. 검색어를 분석/통계 내는 프로그램인데 하루 몇십만건의 검색어와 그외 부가적은 데이터들을 색인하여 놓다보니.. 이게 1년이 넘어가자 인덱스 파일의 크기가 10G를 훌쩍 넘어가버리더군요.. 그래서 이번에 프로그램을 업그레이드 하면서 인덱스 파일을 년도별로 분리시키면서, 루씬에서 제공되는 MultiSearcher를 사용해보기로 하고 개발을 진행하였습니다. 1.단일 인덱스 파일로부터의 검색 그냥 기본적으로 검색을 한다고 하면 위와 같은 방식으로 검색을 하게 됩니다. 루씬에서 제공하는 MultiSearcher를 사용하기는 간단합니다. 위와 같은 단.. 더보기
Lucene 3.0 TokenStream과 AttributeSource. - 2 - 앞에서 AttributeSource에 Attribute들 (term, offset, position, type 등) set 해주면 그 뒤에 오는 Filter나 Tokenizer가 해당 Attribute를 사용 할 수 있다고 했습니다. 각각의 Filter와 Tokenizer는 모두 TokenStream을 상속하고 있고 이 TokenStream은 AttributeSource를 상속받고 있습니다. 이 Filter와 Tokenizer가 서로 데코레이터 패턴으로 물려있기 때문에 앞에서 set한 결과를 뒤에 따라오는 Filter와 Tokenizer가 사용 할 수 있는 것 입니다. (Java의 stream 관련 클래스들을 생각하시면 됩니다.) 소스를 보면 보통 맨 앞단에서 들어오는 String을 잘라내는 역할을 하는.. 더보기
Lucene 3.0 TokenStream과 AttributeSource. - 1 - 루씬이 버전업 되면서 바뀐 부분 중 하나가 이 부분인 것 같습니다. 이전에는 Tokenizer나 TokenFilter 클래스를 만들 때 TokenStream 클래스를 상속받아 만들고 이 TokenStream의 next 메서드를 사용해서 얻어지는 Token을 가지고 데코레이터 패턴으로 적용 된 Filter들이 Token을 처리하는 방식이었습니다. 예를 들어서, Analyzer의 tokenStream 메서드가 위와 같이 정의되어 있다고 하고 분석해야 할 문장이 "검색엔진 개발자" 라고 했을 때 추출 되는 Token을 얻어내기 위해서 next 메서드를 실행했었습니다. 즉, 대략 위와 같은 방식이었죠. next 메서드가 실행 되면 제일 상위의 Tokenizer에서 "검색엔진,(0,4)" 라는 Token을 만들어.. 더보기