Sprievodca po lucenských analyzátoroch
1. Prehľad
Analyzátory Lucene sa používajú na analýzu textu pri indexovaní a prehľadávaní dokumentov.
V našom úvodnom tutoriále sme sa krátko zmienili o analyzátoroch.
V tomto návode budeme diskutovať o bežne používaných analyzátoroch, o tom, ako zostaviť náš vlastný analyzátor a ako priradiť rôzne analyzátory pre rôzne polia dokumentu.
2. Maven závislosti
Najskôr musíme tieto závislosti pridať do našej pom.xml:
org.apache.lucene lucene-core 7.4.0 org.apache.lucene lucene-queryparser 7.4.0 org.apache.lucene lucene-analyzatory-spolocne 7.4.0
Najnovšiu verziu Lucene nájdete tu.
3. Lucene Analyzer
Analyzátory Lucene rozdelili text na tokeny.
Analyzátory pozostávajú hlavne z tokenizérov a filtrov. Rôzne analyzátory pozostávajú z rôznych kombinácií tokenizérov a filtrov.
Na demonštráciu rozdielov medzi bežne používanými analyzátormi použijeme túto nasledujúcu metódu:
analýza verejného zoznamu (text reťazca, analyzátor analyzátora) vyvolá IOException {výsledok výsledku = nový ArrayList (); TokenStream tokenStream = analyzátor.tokenStream (FIELD_NAME, text); CharTermAttribute attr = tokenStream.addAttribute (CharTermAttribute.class); tokenStream.reset (); while (tokenStream.incrementToken ()) {result.add (attr.toString ()); } vrátiť výsledok; }
Táto metóda prevádza daný text na zoznam tokenov pomocou daného analyzátora.
4. Bežné lucenové analyzátory
Teraz sa pozrime na niektoré bežne používané analyzátory Lucene.
4.1. StandardAnalyzer
Začneme s StandardAnalyzer čo je najčastejšie používaný analyzátor:
private static final String SAMPLE_TEXT = "This is baeldung.com Lucene Analyzers test"; @ Test public void whenUseStandardAnalyzer_thenAnalyzed () vyvolá IOException {List result = analyze (SAMPLE_TEXT, new StandardAnalyzer ()); assertThat (výsledok, obsahuje ("baeldung.com", "lucene", "analyzátory", "test")); }
Všimnite si, že StandardAnalyzer dokáže rozpoznať adresy URL a e-maily.
Tiež odstráni zastavovacie slová a generuje malé tokeny.
4.2. StopAnalyzer
The StopAnalyzer pozostáva z LetterTokenizer, LowerCaseFiltera StopFilter:
@ Test public void whenUseStopAnalyzer_thenAnalyzed () vyvolá IOException {List result = analyze (SAMPLE_TEXT, new StopAnalyzer ()); assertThat (result, contains ("baeldung", "com", "lucene", "analyzers", "test")); }
V tomto príklade LetterTokenizer rozdelí text na znaky iné ako písmeno, zatiaľ čo znak StopFilter odstráni stop slová zo zoznamu tokenov.
Avšak na rozdiel od StandardAnalyzer, StopAnalyzer nedokáže rozpoznať adresy URL.
4.3. SimpleAnalyzer
SimpleAnalyzer pozostáva z LetterTokenizer a a LowerCaseFilter:
@ Test public void whenUseSimpleAnalyzer_thenAnalyzed () vyvolá IOException {List result = analyze (SAMPLE_TEXT, new SimpleAnalyzer ()); assertThat (result, contains ("this", "is", "baeldung", "com", "lucene", "analyzers", "test"); }
Tu je SimpleAnalyzer neodstránil zastavovacie slová. Nerozpoznáva tiež adresy URL.
4.4. WhitespaceAnalyzer
The WhitespaceAnalyzer používa iba a WhitespaceTokenizer ktorý rozdeľuje text na medzery:
@Test public void whenUseWhiteSpaceAnalyzer_thenAnalyzed () vyvolá IOException {List result = analyze (SAMPLE_TEXT, new WhitespaceAnalyzer ()); assertThat (výsledok, obsahuje („Toto“, „je“, „baeldung.com“, „Lucene“, „Analyzátory“, „test“)); }
4.5. KeywordAnalyzer
The KeywordAnalyzer tokenizuje vstup do jedného tokenu:
@Test public void whenUseKeywordAnalyzer_thenAnalyzed () hodí IOException {List result = analyze (SAMPLE_TEXT, new KeywordAnalyzer ()); assertThat (výsledok, obsahuje ("Toto je test lucene analyzátorov bacenung.com")); }
The KeywordAnalyzer je užitočné pre polia ako ID a PSČ.
4.6. Analyzátory jazykov
Existujú aj špeciálne analyzátory pre rôzne jazyky, ako napríklad AnglickyAnalyzer, Francúzsky analyzátora Španielsky analyzátor:
@Test public void whenUseEnglishAnalyzer_thenAnalyzed () hodí IOException {List result = analyze (SAMPLE_TEXT, new EnglishAnalyzer ()); assertThat (výsledok, obsahuje ("baeldung.com", "lucen", "analýza", "test")); }
Tu používame AnglickyAnalyzer ktorý sa skladá z StandardTokenizer, StandardFilter, EnglishPossessiveFilter, LowerCaseFilter, StopFiltera PorterStemFilter.
5. Vlastný analyzátor
Ďalej sa pozrime, ako zostaviť náš vlastný analyzátor. Rovnaký vlastný analyzátor zostrojíme dvoma rôznymi spôsobmi.
V prvom príklade použijeme CustomAnalyzer staviteľ na zostavenie nášho analyzátora z preddefinovaných tokenizérov a filtrov:
@Test public void whenUseCustomAnalyzerBuilder_thenAnalyzed () hodí IOException {Analyzer analyzer = CustomAnalyzer.builder () .withTokenizer ("standard") .addTokenFilter ("lowercase") .addTokenFilter ("stop") .addTokenFilter ("stop") veľké písmená ") .build (); Výsledok zoznamu = analýza (SAMPLE_TEXT, analyzátor); assertThat (výsledok, obsahuje („Baeldung.com“, „Lucen“, „Analyz“, „Test“)); }
Náš analyzátor je veľmi podobný AngličtinaAnalyzer, ale namiesto toho použije veľké písmená.
V druhom príklade postavíme rovnaký analyzátor rozšírením Analyzátor abstraktná trieda a prvoradý createComponents () metóda:
verejná trieda MyCustomAnalyzer rozširuje analyzátor {@Override chránený TokenStreamComponents createComponents (reťazec fieldName) {StandardTokenizer src = nový StandardTokenizer (); Výsledok TokenStream = nový StandardFilter (src); výsledok = nový LowerCaseFilter (výsledok); result = new StopFilter (result, StandardAnalyzer.STOP_WORDS_SET); výsledok = nový PorterStemFilter (výsledok); výsledok = nový CapitalisationFilter (výsledok); vrátiť nové TokenStreamComponents (src, výsledok); }}
Môžeme tiež vytvoriť náš vlastný tokenizer alebo filter a v prípade potreby ho pridať do nášho vlastného analyzátora.
Teraz sa pozrime na náš vlastný analyzátor v akcii - použijeme InMemoryLuceneIndex v tomto príklade:
@Test public void givenTermQuery_whenUseCustomAnalyzer_thenCorrect () {InMemoryLuceneIndex luceneIndex = nový InMemoryLuceneIndex (nový RAMDirectory (), nový MyCustomAnalyzer ()); luceneIndex.indexDocument ("úvod", "úvod do lucene"); luceneIndex.indexDocument ("analyzátory", "sprievodca po analyzátoroch lucene"); Dotaz na dopyt = nový TermQuery (nový výraz ("telo", "úvod")); Zoznam dokumentov = luceneIndex.searchIndex (dopyt); assertEquals (1, documents.size ()); }
6. PerFieldAnalyzerWrapper
Nakoniec môžeme priradiť rôzne analyzátory k rôznym poliam pomocou PerFieldAnalyzerWrapper.
Najprv si musíme definovať svoje analyzátorMapa na mapovanie každého analyzátora do konkrétneho poľa:
Map analyzerMap = new HashMap (); analyzerMap.put ("title", nový MyCustomAnalyzer ()); analyzerMap.put ("body", new EnglishAnalyzer ());
Namapovali sme „nadpis“ na náš vlastný analyzátor a „telo“ do anglického analyzátora.
Ďalej si vytvorme našu PerFieldAnalyzerWrapper poskytnutím analyzátorMapa a predvolené Analyzátor:
Obal PerFieldAnalyzerWrapper = nový PerFieldAnalyzerWrapper (nový StandardAnalyzer (), analyzerMap);
Teraz to otestujme:
@Test public void givenTermQuery_whenUsePerFieldAnalyzerWrapper_thenCorrect () {InMemoryLuceneIndex luceneIndex = nový InMemoryLuceneIndex (nový RAMDirectory (), obal); luceneIndex.indexDocument ("úvod", "úvod do lucene"); luceneIndex.indexDocument ("analyzátory", "sprievodca po analyzátoroch lucene"); Dotaz na dopyt = nový TermQuery (nový výraz ("telo", "úvod")); Zoznam dokumentov = luceneIndex.searchIndex (dopyt); assertEquals (1, documents.size ()); dotaz = nový TermQuery (nový výraz ("názov", "úvod")); documents = luceneIndex.searchIndex (dopyt); assertEquals (1, documents.size ()); }
7. Záver
Diskutovali sme o populárnych analyzátoroch Lucene, ako zostaviť vlastný analyzátor a ako používať iný analyzátor pre každé pole.
Celý zdrojový kód nájdete na GitHub.