Lucene: First Impression

Lucene 또는 Lucene Java는 매우 유명한 오픈 소스 검색 엔진 소프트웨어입니다. Lucene은 Apache Lucene 프로젝트에 속해있는데, 이 프로젝트는 Lucene 외에도 NutchHadoop 등을 포함하는 Apache의 검색 소프트웨어 프로젝트입니다.

팀에서 웹크롤한 결과의 질을 가시적으로 만들기 위한 방법의 하나로 Lucene을 사용해보기로 했습니다. Lucene이 사용하기 쉽다는 평은 처로군으로부터 자주 들었지만, 이 정도 일 줄은 몰랐습니다. 팀이 가지고 있는 데이터베이스와 연동해서 콘솔을 통해 검색 가능하게 만드는데, 한시간 밖에 안걸렸습니다. Lucene에 대한 사전지식은 거의 없었다고 봐도 무방합니다. Lucene을 사용하기 위해 참고한 것은 Lucene 소스 코드 내에 들어있는 데모와 데모를 간단하게 설명하고 있는 문서 뿐이었습니다. Lucene에 관한 유일한 책인 ‘루씬 인 액션‘을 살짝 보긴 했으나 책에 등장하는 코드들이 out-of-date 더군요. Lucene을 연동하는 코드를 짜는 데에는 별로 도움이 안되었습니다.

1시간 동안 만든 것은 데모의 코드를 Copy and Paste하면서 만든 Indexer 프로그램과 Searcher 프로그램인데, 각각 인덱싱을 수행하는 프로그램과 생성된 인덱스로부터 검색을 수행하는 프로그램입니다.

Indexer 코드의 중요한 부분만을 보자면 대충 다음과 같습니다.

IndexWriter writer = new IndexWriter(INDEX_DIR, new StandardAnalyzer(), true);

// make lucene document
Document doc = new Document();
doc.add(new Field(“url”, uri, Store.YES, Index.UN_TOKENIZED));
doc.add(new Field(“title”, title, Store.YES, Index.TOKENIZED));
doc.add(new Field(“content”, cpmtemt, Store.YES, Index.TOKENIZED));

// add it to IndexWriter
writer.addDocument(doc);

writer.optimize();
writer.close();

간단히 설명하면, IndexWriter는 인덱스를 생성하는 역할을 하고, 인덱스의 단위는 Document입니다. Document는 복수의 Field를 가질 수 있고, Field 별로 tokenize할 것인가, 인덱스에 Field 내용을 저장할 것인가를 지정할 수 있습니다. Analyzer가 Field를 tokenize하는 역할을 하는데, IndexWriter에 명시한 것 외에 Field 별로 Analyzer를 지정할 수 있습니다.

디자인이 도메인을 그대로 반영하고 있고, 단순하면서도 확장성이 높은, 좋은 API입니다.

Searcher 코드도 한번 들여다 보죠.

IndexReader reader = IndexReader.open(“index”);
Searcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();

QueryParser parser = new QueryParser(“content”, analyzer);
Query query = parser.parse(queryString);

Hits hits = searcher.search(query);

for (int i = 0; i < hits.length(); i++) {

Document doc = hits.doc(i);
String urlString = doc.get(“url”);
String title = doc.get(“title”);
String content = doc.get(“content”);
// …

}

역시 마찬가지로 코드만으로도 이해하기 쉽습니다. 별로 설명할 것이 없네요.

인덱싱 하는데에는 시간이 좀 걸리지만, 한번 인덱싱하고난 후에는 검색 속도는 대단히 빠릅니다. 10만개 정도까지밖에 안해봐서 실제 크기의 데이터에서는 어떨런지는 모르겠습니다.

한편, 한글 관련한 Analyzer 이슈에 대해서는 아직 잘 모르겠습니다만, 한글 검색도 그럭저럭 되는 것 같군요. 좀 더 자세히 알아봐야할 것 같습니다.

현재의 검색 솔루션이 맘에 안든다면, 엔터프라이즈급의 간단한 검색 솔루션으로는 부담없이 연동해서 쓸 수 있는 수준인 것 같습니다.

지금 구글 검색해보니, 좀 더 좋은 튜터리얼 들이 있군요. 참고하세요.

“Lucene: First Impression”에 대한 2개의 생각

  1. Lucene관련하여 한글 형태소 분석기가 아직 구현되지 않은것으로 알고 있습니다. CJKAnalyzer가 있긴 한데 그냥 무조건 글자를 두글자 단위로 겹쳐서 짤라 인덱싱하는 무식한 방법을 사용합니다.
    사이트내의 간단한 검색기능은 몰라도 전문적인 검색기능으로 쓰기에는 한글 형태소 분석기가 참으로 아쉽습니다.

  2. 네, 맞습니다. 이 글을 쓴 후 조사해보니 Standard Analyzer는 토큰 단위의 Exact Match만을 지원하더군요. CJKAnalyzer의 방식은 Bigram 방식이라고 보면 될테고… (그리 무식한 것은…) 자세한 것은 내일 아침에 다시 포스팅을…

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.