これは何?

青空文庫の準備

Indexer

https://github.com/kagyuu/LuceneExam/blob/master/src/main/java/com/mycompany/luceneexam/Indexer.java

package com.mycompany.luceneexam;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.gosen.GosenAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
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.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class Indexer {

    public static void main(String[] args) {
        try {
            File home = new File(System.getProperty("user.home"));

            // インデックスの出力先を定義
            Directory indexDir = FSDirectory.open(new File(home, "Documents/index").toPath());
            // テキストの解析方法(アナライザー)を定義
            //Analyzer analyzer = new StandardAnalyzer(); // 英語用
            Analyzer analyzer = new GosenAnalyzer();
            // 解析方法の設定
            IndexWriterConfig config = new IndexWriterConfig(analyzer);
            // インデックスが既に存在する場合の動作を定義する(OpenMode.CREATE の場合、新規に作成して上書きする)
            config.setOpenMode(OpenMode.CREATE);
            try (IndexWriter writer = new IndexWriter(indexDir, config)) {
                File root = new File(home, "Documents/novels");
                gatherDocs(writer, root);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void gatherDocs(IndexWriter writer, File parent) throws IOException {
        System.out.println(parent.getAbsolutePath());
        for (File child : parent.listFiles()) {
            if (child.isDirectory()) {
                gatherDocs(writer, child);
                continue;
            }
            
            String name = child.getName();
            if (name.startsWith(".")) {
                continue;
            }
            if (name.endsWith("txt")) {  
                System.out.format("FILE:%s\n", name);
                try (BufferedReader br = Files.newBufferedReader(child.toPath(), Charset.forName("Windows-31J"))) {
                    
                    String title = br.readLine();
                    String author = br.readLine();
                    
                    System.out.format("%s %s\n", title, author);
                    
                    // Document に、インデックスに保存する各ファイルの情報を設定する
                    Document doc = new Document();
                    doc.add(new StringField("author", author, Store.YES));
                    doc.add(new StringField("title", title, Store.YES));
                    doc.add(new TextField("contents", br));

                    // インデックスを書き出す
                    writer.addDocument(doc);
                } catch(java.lang.Exception e) {
                    System.out.println("読み込み失敗");
                }
            }
        }
    }
}

Searcher

https://github.com/kagyuu/LuceneExam/blob/master/src/main/java/com/mycompany/luceneexam/Searcher.java

package com.mycompany.luceneexam;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.gosen.GosenAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
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.FSDirectory;

public class Searcher {

    public static void main(String[] args) throws IOException, ParseException {
        try {
	    File home = new File(System.getProperty("user.home"));

            // テキストの解析方法(アナライザー)を定義
            //Analyzer analyzer = new StandardAnalyzer(); // 英語用
            Analyzer analyzer = new GosenAnalyzer();
            // 検索対象のフィールドを第二引数で指定している
            QueryParser parser = new QueryParser("contents", analyzer);

            // 検索文字列を解析する
            String searchText = args[0];
            Query query = parser.parse(searchText);

            // 検索で使用する IndexSearcher を生成する
            Directory indexDir = FSDirectory.open(new File(home, "Documents/index").toPath());
            IndexReader indexReader = DirectoryReader.open(indexDir);
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);

            // 検索を実行する(第二引数は、検索結果の最大数)
            TopDocs results = indexSearcher.search(query, 10);

            // 検索の結果、該当した Document を1つずつ取得する
            for (ScoreDoc scoreDoc : results.scoreDocs) {
                Document doc = indexSearcher.doc(scoreDoc.doc);

                // Document の path を取得して出力する
                String author = doc.get("author");
                String title = doc.get("title");
                System.out.format("%s, %s, %f\n", author, title, scoreDoc.score);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

実行

$ mvn clean compile package dependency:copy-dependencies
$ export CLASSPATH=target/LuceneExam-1.0-SNAPSHOT.jar:target/dependency/*
$ time java com.mycompany.luceneexam.Indexer
...
FILE:219kaneno_oto.txt
錢形平次捕物控 鐘の音
FILE:lavoisier.txt
ラヴォアジエ 石原純
FILE:kasojinbutsu.txt
仮装人物 徳田秋声
FILE:zatsudansho.txt
雑談抄 牧野信一

real	2m32.320s
user	2m44.847s
sys	0m1.516s

Indexファイル作るの相当早いな。10GB処理するのにたかだか2分。色々あって結構良い計算機を衝動買いしちゃったのです

$ time java com.mycompany.luceneexam.Searcher 人生やめたい
久生十蘭, 春雪, 6.566760
MORNING AND EVENING THOUGHTS, 朝に想い、夜に省みる, 6.547380
佐々木邦, 一年の計, 6.488889
坂口安吾, 不可解な失恋に就て, 6.420032
三木清, 如何に読書すべきか, 6.196942
岸田國士, 新劇協会の舞台稽古, 6.195092
THE YELLOW FACE, 土色の顔, 6.138238
三好十郎, 恐怖の季節, 6.082151
和辻哲郎, 露伴先生の思い出, 6.064951
辻潤, ふもれすく, 6.057560

real	0m0.368s
user	0m0.644s
sys	0m0.051s

検索、早!それっぽい題名の小説が検索された

$ time java com.mycompany.luceneexam.Searcher 夜明け前が一番暗い
中谷宇吉郎, 八月三日の夢, 9.644770
クリスマス・ストーリー, 千里眼の村, 9.404030
川端茅舎, 夏の月, 8.961294
THE OLD MAN AND THE SEA, 老人と海, 8.874863
織田作之助, 秋の暈, 8.737694
島崎藤村, 秋草, 8.694632
原民喜, 魔のひととき, 8.631346
坂口安吾, 桐生通信, 8.517919
中谷宇吉郎, I駅の一夜, 8.474227
室生犀星, 寂しき魚, 8.410800

real	0m0.374s
user	0m0.655s
sys	0m0.058s

ほーほー、ずっと遊べるな


Java#Jakarta


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2019-10-29 (火) 02:33:44 (1642d)
Short-URL:
ISBN10
ISBN13
9784061426061