본문 바로가기

Lucene

[about Lucene] 루씬으로 검색엔진 개발하기 - Near Realtime Search-

이번 글에서는
루씬인액션에서 소개되고 있는
Near Realtime Search에 대해서 작성해보려고 합니다.

기본적으로 IndexSearcherIndexWriter에 의한 변경 사항을
바로바로 반영하지를 못 합니다. 일반적으로 commit이 된 이후 IndexSearcher를 새로 생성하여야
IndexWriter에 의한 변경된 내용을 반영 할 수 있습니다.

제가 내부적으로 구현하여 사용하고 있는
프로그램에서도 이러한 부분을 Searcher를 새로 만들어서 사용하고 있습니다.

  RealTimeSearch.java

파일명은 RealTimeSearch이지만 사실 RealTimeSearch에 대한 예제는 아닙니다.

지금까지 루씬에서 IndexWriter에 의한 변경을 IndexSearcher에서 반영하기 위해 사용했던
방식을 테스트케이스 형태로 구현해둔 것 입니다.

우선 init()메서드를 통해 메모리에 문서를 색인하여 놓습니다.
그리고 private으로 deleteDocument, addDocument 메서드를 구현하였습니다.
이를 사용하여 IndexWriter에 의한 변경 내용이 어떻게 반영이 되는지 확인해 볼 것 입니다.

첫번째 테스트케이스 searchAfterDocumentDeleted 에서는
ids가 1인 문서를 찾고...  deleteDocument 메서드를 실행하여 ids가 1인 문서를 삭제합니다.
그리고 다시 ids가 1인 문서를 찾고 있습니다. deleteDocument에서 commit까지 하였지만 이미 생성되어 있던
IndexSearcher는 이 내용을 반영하지 못 합니다.

searchAfterDocumentDeleteIndexReaderReopen 메서드를 보시면
마찬가지로 ids가 1인 문서를 삭제를 한 후 ids가 1인 문서를 검색하는데 그 전에 IndexReader를 다시 생성하는
부분이 있습니다.

IndexReader newReader = indexReader.reopen();
if(newReader != indexReader) {
indexSearcher = new IndexSearcher(newReader);
indexReader.close();
}


바로 이 부분이 지금까지 사용했던 IndexWriter에 의한 변경 내용을 반영하는 방법이었습니다.
이렇게 구현을 해도 기능은 이상없이 잘 적용이 됩니다. 하지만 책에서는 IndexWritercommit 작업이 디스크 IO를 유발하고
기타 부하를 주는 작업이라고 하네요.. 그래서 commit을 하지 않아도 IndexSearcher가 변경된 내용을 반영 할 수 있는
NearRealTime Search가 바로 이번에 루씬인액션에서 소개되었습니다.


NearRealTimeTest.java
코드가 좀 길지만 맨 위 메서드가 책에서 나온 예제이고..
그 아래 두개의 메서드는 첫번째 메서드에서 deprecated된 메서드의 사용을 제가 수정한 메서드 두개입니다.

내용의 핵심은 IndexWrtierIndexReader를 얻어서 이를 사용하여 IndexSearcher를 생성하는 것 입니다.
기본적으로 IndexReader를 다시 open하는 작업은 동일하지만 IndexWritercommit을 하지 않아도
변경 된 내용을 IndexSearcher가 반영 할 수 있다는 부분이 다른 점 입니다.

IndexSearcher는 아래와 같이 생성합니다. 

IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED);
IndexReader reader = writer.getReader();
IndexSearcher searcher = new IndexSearcher(reader);


다만, 현재 3.3 버전에서는 IndexWriter.getReader 메서드가 deprecated처리가 되었기 때문에
이 부분을 아래와 같이 수정하였습니다.

IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_33, new WhitespaceAnalyzer(Version.LUCENE_33));
IndexWriter writer = new IndexWriter(dir, conf);
IndexReader reader = IndexReader.open(writer, true);
IndexSearcher searcher = new IndexSearcher(reader);


테스트케이스를 보시면 commit을 하지 않아도 문서가 추가되고 삭제된 내용이 IndexSearcher에 의해서
반영되고 있는 것을 확인 하실 수 있습니다.

https://github.com/need4spd/aboutLucene
에서 체크아웃 받으 실 수 있습니다.