자바 검색엔진 "아파치 루씬(lucene) 8.7.0" 적용기 - 2/2
2021. 1. 22. 23:04ㆍDevelopment/[Java] 자바
728x90
1편 - kplog.tistory.com/285 |
지난 시간에 1개의 파일을 읽어서 해당 파일의 특정 단어의 위치에 대한 검색을 빠르게 하는 방법으로 "아파치 루씬" 도입을 고려했다.
테스트를 거듭한 결과, 역시 아파치 루씬의 단어 검색에 성공을 했고, 그 속도에 놀라게 되었다.
역시 코딩은 집에서 편하게 쉬는 시간(?)에 해야 해결이 잘되는 것 같은 것은 진리인가..
우선 아파치 루씬을 구현하기 위한 큰 구조는 다음과 같다.
*. 사전 필요 작업 (라이브러리 의존성 추가)
implementation group: 'org.apache.lucene', name: 'lucene-core', version: '8.7.0'
implementation group: 'org.apache.lucene', name: 'lucene-analyzers-common', version: '8.7.0'
implementation group: 'org.apache.lucene', name: 'lucene-codecs', version: '8.7.0'
implementation group: 'org.apache.lucene', name: 'lucene-queryparser', version: '8.7.0'
[ 인덱스 만들기 작업 ]
(1) 인덱싱할 대상 파일을 지정한다.
(2) 대상파일을 인덱싱할 인덱스 파일의 저장 디렉토리를 지정한다.
(3) 인덱스 Writer 작업 (중요) - "IndexWriter"
(4) 인덱싱을 위한 도큐먼트 추가 작업 (라인넘버와 해당 라인의 문자열)
[ 인덱스 찾기 작업 ]
(1) 인덱스 파일에서 인덱스 내용을 검색한다 - "IndexReader, IndexSearcher > QueryParser"
실제 순서에 따라 구현을 하자면 다음과 같다.
[ 인덱스 만들기 작업 ]
public static void luceneMakeIndex() throws Exception {
//(1) 인덱싱할 대상 파일을 지정한다.
File file = new File("sample.txt");
//(2) 대상파일을 인덱싱할 인덱스 파일의 저장 디렉토리를 지정한다.
File fileIndex = new File("sample.txt.index");
//(3) 인덱스 Writer 작업
FSDirectory dir = FSDirectory.open(Paths.get(fileIndex.toURI()));
IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());
IndexWriter writer = new IndexWriter(dir, config);
//기존 정보 삭제
writer.deleteAll();
//파일을 라인 단위로 읽기
try(LineNumberReader lineNumberReader = new LineNumberReader(Files.newBufferedReader(Paths.get(file.toURI())))) {
lineNumberReader.lines().forEach(s -> {
int line = lineNumberReader.getLineNumber();
try {
//(4) 인덱싱을 위한 도큐먼트 추가 작업 (라인넘버와 해당 라인의 문자열)
Document document = new Document();
document.add(new StringField("id", String.valueOf(line) , Field.Store.YES));
document.add(new TextField("body", s , Field.Store.YES));
writer.addDocument(document);
} catch (IOException e) {
e.printStackTrace();
}
});
writer.commit();
writer.close();
}
catch (IOException | SecurityException e) {
e.printStackTrace();
}
}
[ 인덱스 찾기 작업 ]
public static void luceneFindIndex() throws Exception {
//인덱스 디렉토리 위치
File fileIndex = new File("sample.txt.index");
//인덱스 찾기 이니셜라이징
Directory dir = FSDirectory.open(Paths.get(fileIndex.toURI()));
IndexReader reader = DirectoryReader.open(dir);
IndexSearcher searcher = new IndexSearcher(reader);
//라인으로 찾아보기
QueryParser qp = new QueryParser("id", new StandardAnalyzer());
Query idQuery = qp.parse("1");
TopDocs foundDocsIdx = searcher.search(idQuery, 10);
//당연히 라인이니까 1개여야...
System.out.println("총 찾은 갯수 (라인) :: " + foundDocsIdx.totalHits);
for (ScoreDoc sd : foundDocsIdx.scoreDocs)
{
Document d = searcher.doc(sd.doc);
//해당 라인의 내용보기
System.out.println(String.format(d.get("body")));
}
//특정 단어로 찾아보기
QueryParser qp = new QueryParser("body", new StandardAnalyzer());
Query wordQuery = qp.parse(word);
TopDocs foundDocsBody = searcher.search(wordQuery, 10);
System.out.println("총 찾은 갯수 (단어) :: " + foundDocsBody.totalHits);
for (ScoreDoc sd : foundDocsBody.scoreDocs)
{
Document d = searcher.doc(sd.doc);
//해당 단어의 라인 위치
System.out.println(String.format(d.get("id")));
}
}
사실 구현한 소스의 원리만 파악하면 크게 어려울 것이 없다. (함수를 외우는게 어렵지만..)
다시한번 정리하자면 아래의 과정으로 정리할 수 있을 것 같다.
인덱스할 파일 지정 > 인덱스 만들기(IndexWriter) > 인덱스 찾기 (IndexReader, IndexSearcher) 만들기 > 찾기 (
QueryParser)
Mission Accomplished!
728x90
반응형
'Development > [Java] 자바' 카테고리의 다른 글
mac java 설치 및 환경변수 path 설정 (0) | 2024.07.16 |
---|---|
IntelliJ 자바 프로젝트에 VM 옵션 추가하기 (0) | 2023.09.22 |
자바 검색엔진 "아파치 루씬(lucene) 8.7.0" 적용기 - 1/2 (0) | 2021.01.20 |
[자바] 멀티쓰레드 병렬처리 - stream 방식 ExecutorService, Future 방식 (0) | 2020.11.24 |
[자바] 배열 중복값 검사 (0) | 2013.01.30 |