Luceneを使った簡単なファイル検索

Luceneを使用した簡単なファイル検索

1. 概要

Apache Luceneは全文検索エンジンであり、さまざまなプログラミング言語で使用できます。 Luceneの使用を開始するには、紹介のarticle hereを参照してください。

この簡単な記事では、テキストファイルにインデックスを付け、そのファイル内のサンプルStringsとテキストスニペットを検索します。

2. Mavenセットアップ

最初に必要な依存関係を追加しましょう:


    org.apache.lucene
    lucene-core
    7.1.0

最新バージョンはhereで見つけることができます。

また、検索クエリを解析するには、次のものが必要です。


    org.apache.lucene
    lucene-queryparser
    7.1.0

最新バージョンhereを確認することを忘れないでください。

3. ファイルシステムディレクトリ

ファイルにインデックスを付けるには、最初にファイルシステムインデックスを作成する必要があります。

Luceneは、ファイルシステムインデックスを作成するためのFSDirectoryクラスを提供します。

Directory directory = FSDirectory.open(Paths.get(indexPath));

ここで、indexPathはディレクトリの場所です。 If the directory doesn’t exist, Lucene will create it.

Luceneは、抽象FSDirectoryクラスの3つの具体的な実装を提供します。SimpleFSDirectory, NIOFSDirectory, and MMapDirectory.それぞれが特定の環境で特別な問題を抱えている可能性があります。

たとえば、SimpleFSDirectory has poor concurrent performance as it blocks when multiple threads read from the same file.

同様に、NIOFSDirectory and MMapDirectory implementations face file-channel issues in Windows and memory release problems respectively.

To overcome such environment peculiarities Lucene provides the FSDirectory.open() method.呼び出されると、環境に応じて最適な実装を選択しようとします。

4. インデックステキストファイル

インデックスディレクトリを作成したら、先に進んでファイルをインデックスに追加しましょう。

public void addFileToIndex(String filepath) {

    Path path = Paths.get(filepath);
    File file = path.toFile();
    IndexWriterConfig indexWriterConfig
     = new IndexWriterConfig(analyzer);
    Directory indexDirectory = FSDirectory
      .open(Paths.get(indexPath));
    IndexWriter indexWriter = new IndexWriter(
      indexDirectory, indexWriterConfig);
    Document document = new Document();

    FileReader fileReader = new FileReader(file);
    document.add(
      new TextField("contents", fileReader));
    document.add(
      new StringField("path", file.getPath(), Field.Store.YES));
    document.add(
      new StringField("filename", file.getName(), Field.Store.YES));

    indexWriter.addDocument(document);
    indexWriter.close();
}

ここでは、「path」と「filename」という名前の2つのStringFieldsと、「contents」という名前のTextFieldを持つドキュメントを作成します。

fileReaderインスタンスを2番目のパラメーターとしてTextFieldに渡すことに注意してください。 ドキュメントは、IndexWriter.を使用してインデックスに追加されます

TextFieldまたはStringFieldコンストラクターの3番目の引数は、フィールドの値も格納されるかどうかを示します。

最後に、IndexWriterclose()を呼び出して、インデックスファイルからロックを正常に閉じて解放します。

5. インデックス付きファイルの検索

次に、インデックスを作成したファイルを検索しましょう。

public List searchFiles(String inField, String queryString) {
    Query query = new QueryParser(inField, analyzer)
      .parse(queryString);
    Directory indexDirectory = FSDirectory
      .open(Paths.get(indexPath));
    IndexReader indexReader = DirectoryReader
      .open(indexDirectory);
    IndexSearcher searcher = new IndexSearcher(indexReader);
    TopDocs topDocs = searcher.search(query, 10);

    return topDocs.scoreDocs.stream()
      .map(scoreDoc -> searcher.doc(scoreDoc.doc))
      .collect(Collectors.toList());
}

機能をテストしましょう:

@Test
public void givenSearchQueryWhenFetchedFileNamehenCorrect(){
    String indexPath = "/tmp/index";
    String dataPath = "/tmp/data/file1.txt";

    Directory directory = FSDirectory
      .open(Paths.get(indexPath));
    LuceneFileSearch luceneFileSearch
      = new LuceneFileSearch(directory, new StandardAnalyzer());

    luceneFileSearch.addFileToIndex(dataPath);

    List docs = luceneFileSearch
      .searchFiles("contents", "consectetur");

    assertEquals("file1.txt", docs.get(0).get("filename"));
}

場所indexPathにファイルシステムインデックスを作成し、file1.txt.にインデックスを付ける方法に注目してください。

次に、“contents”フィールドでStringconsectetur”を検索するだけです。

6. 結論

この記事は、Apache Luceneを使用したテキストのインデックス作成と検索の簡単なデモでした。 Luceneのインデックス作成、焼き付け、クエリの詳細については、introduction to Lucene articleを参照してください。

いつものように、例のコードはover on Githubにあります。