Luceneアナライザーガイド

Luceneアナライザーのガイド

1. 概要

Luceneアナライザーは、ドキュメントのインデックス作成および検索中にテキストを分析するために使用されます。

アナライザーについては、introductory tutorialで簡単に説明しました。

このチュートリアルでは、we’ll discuss commonly used Analyzers, how to construct our custom analyzer and how to assign different analyzers for different document fields

2. Mavenの依存関係

まず、これらの依存関係をpom.xmlに追加する必要があります。


    org.apache.lucene
    lucene-core
    7.4.0


    org.apache.lucene
    lucene-queryparser
    7.4.0


    org.apache.lucene
    lucene-analyzers-common
    7.4.0

Luceneの最新バージョンはhereにあります。

3. Luceneアナライザー

Lucene Analyzerはテキストをトークンに分割します。

Analyzers mainly consist of tokenizers and filters.さまざまなアナライザーは、トークナイザーとフィルターのさまざまな組み合わせで構成されます。

一般的に使用されるアナライザーの違いを示すために、次の方法を使用します。

public List analyze(String text, Analyzer analyzer) throws IOException{
    List result = new ArrayList();
    TokenStream tokenStream = analyzer.tokenStream(FIELD_NAME, text);
    CharTermAttribute attr = tokenStream.addAttribute(CharTermAttribute.class);
    tokenStream.reset();
    while(tokenStream.incrementToken()) {
       result.add(attr.toString());
    }
    return result;
}

このメソッドは、指定されたアナライザーを使用して、指定されたテキストをトークンのリストに変換します。

4. 一般的なLuceneアナライザー

それでは、一般的に使用されているLuceneアナライザーをいくつか見てみましょう。

4.1. StandardAnalyzer

最も一般的に使用されるアナライザーであるStandardAnalyzerから始めます。

private static final String SAMPLE_TEXT
  = "This is example.com Lucene Analyzers test";

@Test
public void whenUseStandardAnalyzer_thenAnalyzed() throws IOException {
    List result = analyze(SAMPLE_TEXT, new StandardAnalyzer());

    assertThat(result,
      contains("example.com", "lucene", "analyzers","test"));
}

StandardAnalyzerはURLとメールを認識できることに注意してください。

また、ストップワードを削除し、生成されたトークンを小文字にします。

4.2. StopAnalyzer

StopAnalyzerは、LetterTokenizer, LowerCaseFilterStopFilter:で構成されます

@Test
public void whenUseStopAnalyzer_thenAnalyzed() throws IOException {
    List result = analyze(SAMPLE_TEXT, new StopAnalyzer());

    assertThat(result,
      contains("example", "com", "lucene", "analyzers", "test"));
}

この例では、LetterTokenizer はテキストを文字以外の文字で分割し、StopFilterはトークンリストからストップワードを削除します。

ただし、StandardAnalyzerとは異なり、StopAnalyzerはURLを認識できません。

4.3. SimpleAnalyzer

SimpleAnalyzerは、LetterTokenizerLowerCaseFilterで構成されます。

@Test
public void whenUseSimpleAnalyzer_thenAnalyzed() throws IOException {
    List result = analyze(SAMPLE_TEXT, new SimpleAnalyzer());

    assertThat(result,
      contains("this", "is", "example", "com", "lucene", "analyzers", "test"));
}

ここで、SimpleAnalyzerはストップワードを削除しませんでした。 また、URLも認識しません。

4.4. WhitespaceAnalyzer

WhitespaceAnalyzerは、テキストを空白文字で分割するWhitespaceTokenizerのみを使用します。

@Test
public void whenUseWhiteSpaceAnalyzer_thenAnalyzed() throws IOException {
    List result = analyze(SAMPLE_TEXT, new WhitespaceAnalyzer());

    assertThat(result,
      contains("This", "is", "example.com", "Lucene", "Analyzers", "test"));
}

4.5. KeywordAnalyzer

KeywordAnalyzerは、入力を単一のトークンにトークン化します。

@Test
public void whenUseKeywordAnalyzer_thenAnalyzed() throws IOException {
    List result = analyze(SAMPLE_TEXT, new KeywordAnalyzer());

    assertThat(result, contains("This is example.com Lucene Analyzers test"));
}

KeywordAnalyzer isは、IDや郵便番号などのフィールドに役立ちます。

4.6. 言語アナライザー

EnglishAnalyzerFrenchAnalyzerSpanishAnalyzerなどのさまざまな言語用の特別なアナライザーもあります。

@Test
public void whenUseEnglishAnalyzer_thenAnalyzed() throws IOException {
    List result = analyze(SAMPLE_TEXT, new EnglishAnalyzer());

    assertThat(result, contains("example.com", "lucen", "analyz", "test"));
}

ここでは、StandardTokenizerStandardFilterEnglishPossessiveFilterLowerCaseFilterStopFilter、およびPorterStemFilterで構成されるEnglishAnalyzerを使用しています。 s。

5. カスタムアナライザー

次に、カスタムアナライザーを構築する方法を見てみましょう。 同じカスタムアナライザーを2つの異なる方法で構築します。

最初の例では、we’ll use the CustomAnalyzer builder to construct our analyzer from predefined tokenizers and filters

@Test
public void whenUseCustomAnalyzerBuilder_thenAnalyzed() throws IOException {
    Analyzer analyzer = CustomAnalyzer.builder()
      .withTokenizer("standard")
      .addTokenFilter("lowercase")
      .addTokenFilter("stop")
      .addTokenFilter("porterstem")
      .addTokenFilter("capitalization")
      .build();
    List result = analyze(SAMPLE_TEXT, analyzer);

    assertThat(result, contains("example.com", "Lucen", "Analyz", "Test"));
}

私たちのアナライザーはEnglishAnalyzerに非常に似ていますが、代わりにトークンを大文字にします。

2番目の例では、we’ll build the same analyzer by extending the Analyzer abstract class and overriding the createComponents() method

public class MyCustomAnalyzer extends Analyzer {

    @Override
    protected TokenStreamComponents createComponents(String fieldName) {
        StandardTokenizer src = new StandardTokenizer();
        TokenStream result = new StandardFilter(src);
        result = new LowerCaseFilter(result);
        result = new StopFilter(result,  StandardAnalyzer.STOP_WORDS_SET);
        result = new PorterStemFilter(result);
        result = new CapitalizationFilter(result);
        return new TokenStreamComponents(src, result);
    }
}

カスタムトークナイザーまたはフィルターを作成し、必要に応じてカスタムアナライザーに追加することもできます。

次に、カスタムアナライザーの動作を見てみましょう。この例ではInMemoryLuceneIndexを使用します。

@Test
public void givenTermQuery_whenUseCustomAnalyzer_thenCorrect() {
    InMemoryLuceneIndex luceneIndex = new InMemoryLuceneIndex(
      new RAMDirectory(), new MyCustomAnalyzer());
    luceneIndex.indexDocument("introduction", "introduction to lucene");
    luceneIndex.indexDocument("analyzers", "guide to lucene analyzers");
    Query query = new TermQuery(new Term("body", "Introduct"));

    List documents = luceneIndex.searchIndex(query);
    assertEquals(1, documents.size());
}

6. PerFieldAnalyzerWrapper

最後に、we can assign different analyzers to different fields using PerFieldAnalyzerWrapper

まず、analyzerMapを定義して、各アナライザーを特定のフィールドにマップする必要があります。

Map analyzerMap = new HashMap<>();
analyzerMap.put("title", new MyCustomAnalyzer());
analyzerMap.put("body", new EnglishAnalyzer());

「タイトル」をカスタムアナライザーに、「ボディ」をEnglishAnalyzerにマッピングしました。

次に、analyzerMapとデフォルトのAnalyzerを指定して、PerFieldAnalyzerWrapperを作成しましょう。

PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(
  new StandardAnalyzer(), analyzerMap);

それでは、テストしてみましょう。

@Test
public void givenTermQuery_whenUsePerFieldAnalyzerWrapper_thenCorrect() {
    InMemoryLuceneIndex luceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), wrapper);
    luceneIndex.indexDocument("introduction", "introduction to lucene");
    luceneIndex.indexDocument("analyzers", "guide to lucene analyzers");

    Query query = new TermQuery(new Term("body", "introduct"));
    List documents = luceneIndex.searchIndex(query);
    assertEquals(1, documents.size());

    query = new TermQuery(new Term("title", "Introduct"));
    documents = luceneIndex.searchIndex(query);
    assertEquals(1, documents.size());
}

7. 結論

人気のあるLuceneアナライザー、カスタムアナライザーの作成方法、フィールドごとに異なるアナライザーの使用方法について説明しました。

完全なソースコードはfound on GitHubにすることができます。