Panduan untuk Lucene Analyzers

1. Ikhtisar

Lucene Analyzer digunakan untuk menganalisis teks saat mengindeks dan mencari dokumen.

Kami menyebutkan penganalisis secara singkat dalam tutorial pengantar kami.

Dalam tutorial ini, kita akan membahas Penganalisis yang biasa digunakan, cara membuat penganalisis kustom, dan cara menetapkan penganalisis yang berbeda untuk bidang dokumen yang berbeda .

2. Ketergantungan Maven

Pertama, kita perlu menambahkan dependensi ini ke pom.xml kita :

 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 

Versi Lucene terbaru dapat ditemukan di sini.

3. Penganalisis Lucene

Penganalisis Lucene membagi teks menjadi token.

Penganalisis terutama terdiri dari tokenizers dan filter. Penganalisis yang berbeda terdiri dari kombinasi tokenizer dan filter yang berbeda.

Untuk mendemonstrasikan perbedaan antara penganalisis yang umum digunakan, kami akan menggunakan metode berikut ini:

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; }

Metode ini mengubah teks tertentu menjadi daftar token menggunakan penganalisis yang diberikan.

4. Alat Analisis Lucene Umum

Sekarang, mari kita lihat beberapa alat analisa Lucene yang umum digunakan.

4.1. StandardAnalyzer

Kami akan mulai dengan StandardAnalyzer yang merupakan penganalisis yang paling umum digunakan:

private static final String SAMPLE_TEXT = "This is baeldung.com Lucene Analyzers test"; @Test public void whenUseStandardAnalyzer_thenAnalyzed() throws IOException { List result = analyze(SAMPLE_TEXT, new StandardAnalyzer()); assertThat(result, contains("baeldung.com", "lucene", "analyzers","test")); }

Perhatikan bahwa StandardAnalyzer dapat mengenali URL dan email.

Juga, itu menghapus kata-kata berhenti dan menurunkan token yang dihasilkan.

4.2. StopAnalyzer

The StopAnalyzer terdiri dari LetterTokenizer, LowerCaseFilter , dan StopFilter:

@Test public void whenUseStopAnalyzer_thenAnalyzed() throws IOException { List result = analyze(SAMPLE_TEXT, new StopAnalyzer()); assertThat(result, contains("baeldung", "com", "lucene", "analyzers", "test")); }

Dalam contoh ini, LetterTokenizer membagi teks dengan karakter non-huruf, sementara StopFilter menghapus kata-kata berhenti dari daftar token.

Namun, tidak seperti StandardAnalyzer , StopAnalyzer tidak dapat mengenali URL.

4.3. SimpleAnalyzer

SimpleAnalyzer terdiri dari LetterTokenizer dan LowerCaseFilter :

@Test public void whenUseSimpleAnalyzer_thenAnalyzed() throws IOException { List result = analyze(SAMPLE_TEXT, new SimpleAnalyzer()); assertThat(result, contains("this", "is", "baeldung", "com", "lucene", "analyzers", "test")); }

Di sini, SimpleAnalyzer tidak menghapus kata stop. Itu juga tidak mengenali URL.

4.4. WhitespaceAnalyzer

The WhitespaceAnalyzer menggunakan hanya WhitespaceTokenizer yang memecah teks dengan karakter spasi:

@Test public void whenUseWhiteSpaceAnalyzer_thenAnalyzed() throws IOException { List result = analyze(SAMPLE_TEXT, new WhitespaceAnalyzer()); assertThat(result, contains("This", "is", "baeldung.com", "Lucene", "Analyzers", "test")); }

4.5. KeywordAnalyzer

The KeywordAnalyzer tokenizes masukan ke tanda tunggal:

@Test public void whenUseKeywordAnalyzer_thenAnalyzed() throws IOException { List result = analyze(SAMPLE_TEXT, new KeywordAnalyzer()); assertThat(result, contains("This is baeldung.com Lucene Analyzers test")); }

The KeywordAnalyzer berguna untuk bidang-bidang seperti id dan zipcodes.

4.6. Penganalisis Bahasa

Ada juga penganalisis khusus untuk berbagai bahasa seperti EnglishAnalyzer , FrenchAnalyzer , dan SpanishAnalyzer :

@Test public void whenUseEnglishAnalyzer_thenAnalyzed() throws IOException { List result = analyze(SAMPLE_TEXT, new EnglishAnalyzer()); assertThat(result, contains("baeldung.com", "lucen", "analyz", "test")); }

Di sini, kami menggunakan EnglishAnalyzer yang terdiri dari StandardTokenizer , StandardFilter , EnglishPossessiveFilter , LowerCaseFilter , StopFilter , dan PorterStemFilter .

5. Penganalisis Kustom

Selanjutnya, mari kita lihat cara membuat penganalisis kustom kami. Kami akan membuat penganalisis khusus yang sama dengan dua cara berbeda.

Pada contoh pertama, kita akan menggunakan pembuat CustomAnalyzer untuk membuat penganalisis dari tokenizer dan filter yang telah ditentukan sebelumnya :

@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("Baeldung.com", "Lucen", "Analyz", "Test")); }

Penganalisis kami sangat mirip dengan EnglishAnalyzer , tetapi menggunakan huruf besar sebagai gantinya.

Dalam contoh kedua, kita akan membuat penganalisis yang sama dengan memperluas kelas abstrak Analyzer dan mengganti metode createComponents () :

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); } }

Kami juga dapat membuat tokenizer atau filter kustom kami dan menambahkannya ke penganalisis kustom kami jika diperlukan.

Now, let's see our custom analyzer in action – we'll use InMemoryLuceneIndex in this example:

@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

Finally, we can assign different analyzers to different fields using PerFieldAnalyzerWrapper.

First, we need to define our analyzerMap to map each analyzer to a specific field:

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

We mapped the “title” to our custom analyzer and the “body” to the EnglishAnalyzer.

Next, let's create our PerFieldAnalyzerWrapper by providing the analyzerMap and a default Analyzer:

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

Now, let's test it:

@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. Conclusion

We discussed popular Lucene Analyzers, how to build a custom analyzer and how to use a different analyzer per field.

Kode sumber lengkap dapat ditemukan di GitHub.