[java] 아파치 루신(Apache Lucene)을 활용한 유사한 질문 검색 기능 구현

목차

  1. 아파치 루신 소개
  2. 유사한 질문 검색 기능 구현 방법
  3. 코드 예시
  4. 참고 자료

아파치 루신 소개

아파치 루신은 자바로 작성된 검색 라이브러리로, 풀 텍스트 기능을 제공합니다. 루신은 빠른 검색 속도와 강력한 검색 기능을 특징으로 하며, 다양한 언어의 검색 엔진 개발에 활용됩니다.

유사한 질문 검색 기능 구현 방법

유사한 질문 검색 기능을 구현하기 위해서는 먼저 아파치 루신을 프로젝트에 추가해야 합니다. Maven 등을 이용하여 아파치 루신을 프로젝트에 의존성으로 추가할 수 있습니다.

먼저, 검색할 질문들을 저장할 인덱스를 생성해야 합니다. 아파치 루신은 인덱스를 생성하여 효율적인 검색을 제공합니다. 인덱스는 검색할 문서들을 특정 필드에 저장하고, 그 필드를 기준으로 검색을 수행할 수 있게 해줍니다.

검색 기능을 구현하기 위해선, 아파치 루신의 QueryParser를 사용하여 검색 쿼리를 파싱하고, 유사한 질문을 검색하는데 필요한 쿼리를 생성해야 합니다. 유사한 질문을 검색하기 위해선, 루신의 유사도 측정 알고리즘 중 하나인 BM25F 알고리즘을 활용할 수 있습니다.

코드 예시

아래는 아파치 루신을 사용하여 유사한 질문 검색을 수행하는 예시 코드입니다.

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.ko.KoreanAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;

import java.io.IOException;

public class SimilarQuestionSearch {
    public static void main(String[] args) throws IOException, ParseException {
        Analyzer analyzer = new KoreanAnalyzer();
        Directory index = new RAMDirectory();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        IndexWriter writer = new IndexWriter(index, config);

        // 검색할 질문들을 인덱스에 추가
        addQuestion(writer, "아파치 루신을 활용한 유사한 질문 검색 기능은 어떻게 구현할 수 있을까요?");
        addQuestion(writer, "아파치 루신을 사용하여 유사한 질문을 검색할 수 있을까요?");
        writer.close();

        // 유사한 질문 검색
        String queryStr = "유사한 질문 검색";
        Query query = new QueryParser("contents", analyzer).parse(queryStr);

        int hitsPerPage = 10;
        IndexSearcher searcher = new IndexSearcher(index);
        TopDocs docs = searcher.search(query, hitsPerPage);
        ScoreDoc[] hits = docs.scoreDocs;

        // 검색 결과 출력
        System.out.println("유사한 질문 검색 결과:");
        for (int i = 0; i < hits.length; i++) {
            Document doc = searcher.doc(hits[i].doc);
            System.out.println((i + 1) + ". " + doc.get("question"));
        }
    }

    private static void addQuestion(IndexWriter writer, String question) throws IOException {
        Document doc = new Document();
        doc.add(new StringField("question", question, Field.Store.YES));
        doc.add(new TextField("contents", question, Field.Store.NO));
        writer.addDocument(doc);
    }
}

참고 자료