全文検索システムApache Luceneを使ってみる

2009/04/11 13:59Update
TAGS: Apache | Lucene | 全文検索

Apache Luceneを使って、ファイルシステムの全文検索機能を構築例です。

Apache Luceneについて


Apache Lucene - Javaによる高機能な全文検索システム

Apache Lucene使い方概要


1、lucene for javaライブラリをダウンロードします。
2、中にあるlucene-core-x.y.z.jarをclasspathに通します。
※x.y.zはluceneのバージョン番号
3、luceneでインデックス作成
4、luceneで検索

Apache Luceneでファイル検索


LuceneTextFileIndexer.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.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.FSDirectory;

public class LuceneTextFileIndexer {

    public static void main(String[] args) throws Exception {
        // 全文検索をしたいファイルを格納するフォルダを指定します
        File fileDir = new File("C:\\lucene\\files");

        // インデックスを格納するフォルダ
        File indexDir = new File("c:\\lucene\\index");

        index(fileDir, indexDir); // インデックス
        query(indexDir); // 検索
    }

    private static void index(File fileDir, File indexDir) throws IOException {

        // インデックス作成
        Analyzer luceneAnalyzer = new StandardAnalyzer();
        IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer,
                new IndexWriter.MaxFieldLength(999999));

        File[] textFiles = fileDir.listFiles();
        long startTime = new Date().getTime();

        // ファイルごとのインデックス作成
        for (int i = 0; i < textFiles.length; i++) {
            if (textFiles[i].isFile()
                    && textFiles[i].getName().endsWith(".txt")) {
                System.out.println(" ファイル:  " + textFiles[i].getCanonicalPath()
                        + " インデックス中... ");
                
                indexFileContent(indexWriter, textFiles[i].getCanonicalPath(), "Shift-JIS");
            }
        }
        // インデックスの最適化
        indexWriter.optimize();
        indexWriter.close();

        // インデックス時間をログ
        long endTime = new Date().getTime();
        System.out.println("インデックス時間:" + (endTime - startTime));
    }

    static void addDoc(IndexWriter writer, Document doc, String key, String value) throws IOException {
        doc.add(new Field(key, value, Store.YES, Index.ANALYZED));
        writer.addDocument(doc);
    }

    //ファイル内容を行ごとにインデックスに追加
    private static void indexFileContent(IndexWriter writer, String fileName, String charset)
            throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                new FileInputStream(fileName), charset));
        String line = new String();

        int lineNo = 0;
        while ((line = reader.readLine()) != null) {
            Document doc = new Document();
            addDoc(writer, doc, "FilePath", fileName);
            lineNo ++;
            addDoc(writer, doc, "FileContent", lineNo + "行目:" + line);
        }
        reader.close();
    }

    //検索してみる
    private static void query(File indexDir) throws IOException {
        String queryString = "検索";
        Query query = null;

        long startTime = new Date().getTime();

        // indexフォルダ
        IndexSearcher searcher = new IndexSearcher(FSDirectory
                .getDirectory(indexDir));

        Analyzer analyzer = new StandardAnalyzer();
        try {
            // FileContent から検索
            QueryParser qp = new QueryParser("FileContent", analyzer);
            query = qp.parse(queryString);
        } catch (ParseException e) {
        }
        if (searcher != null) {
            TopDocs topdocs = searcher.search(query, 10000);
            if (topdocs.totalHits > 0) {
                System.out.println("検索結果:" + topdocs.totalHits + " 件。 ");
                for (ScoreDoc scoreDoc : topdocs.scoreDocs) {

                    Document doc = searcher.doc(scoreDoc.doc);

                    System.out.println(doc.get("FilePath"));
                    System.out.println(doc.get("FileContent"));
                }
            }
        }

        long endTime = new Date().getTime();
        System.out.println("検索時間:" + (endTime - startTime));
    }
}


実行:
1)C:\lucene\filesに適当なテキストファイルを複数作成します。
2)上のプログラムを実行します。

C:\>javac LuceneTextFileIndexer.java
C:\>java LuceneTextFileIndexer
ファイル:  C:\lucene\files\LuceneTest.txt インデックス中...
ファイル:  C:\lucene\files\LuceneTest2.txt インデックス中...
インデックス時間:234
検索結果:3 件。
C:\lucene\files\LuceneTest.txt
4行目:検索
C:\lucene\files\LuceneTest2.txt
6行目:検索
C:\lucene\files\LuceneTest2.txt
1行目:apache lucene全文検索。
検索時間:78

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation