Gids voor Lucene Analyzers

1. Overzicht

Lucene Analyzers worden gebruikt om tekst te analyseren tijdens het indexeren en doorzoeken van documenten.

We noemden analyzers kort in onze inleidende tutorial.

In deze tutorial we bespreken veelgebruikte analysers, hoe u onze aangepaste analyser kunt bouwen en hoe u verschillende analysers voor verschillende documentvelden kunt toewijzen.

2. Maven afhankelijkheden

Ten eerste moeten we deze afhankelijkheden toevoegen aan onze pom.xml:

 org.apache.lucene lucene-core 7.4.0 org.apache.lucene lucene-queryparser 7.4.0 org.apache.lucene lucene-analysers-algemeen 7.4.0 

De nieuwste Lucene-versie is hier te vinden.

3. Lucene Analyzer

Lucene Analyzers splitsen de tekst op in tokens.

Analyzers bestaan ​​voornamelijk uit tokenizers en filters. Verschillende analysers bestaan ​​uit verschillende combinaties van tokenizers en filters.

Om het verschil tussen veelgebruikte analysers aan te tonen, gebruiken we de volgende methode:

openbare lijstanalyse (String-tekst, Analyzer-analysator) genereert IOException {List result = new ArrayList (); TokenStream tokenStream = analyzer.tokenStream (FIELD_NAME, tekst); CharTermAttribute attr = tokenStream.addAttribute (CharTermAttribute.class); tokenStream.reset (); while (tokenStream.incrementToken ()) {result.add (attr.toString ()); } resultaat teruggeven; }

Deze methode zet een bepaalde tekst om in een lijst met tokens met behulp van de opgegeven analysator.

4. Gemeenschappelijke Lucene Analyzers

Laten we nu eens kijken naar enkele veelgebruikte Lucene-analysers.

4.1. StandardAnalyzer

We beginnen met de StandardAnalyzer welke is de meest gebruikte analyser:

private static final String SAMPLE_TEXT = "Dit is baeldung.com Lucene Analyzers-test"; @Test openbare leegte whenUseStandardAnalyzer_thenAnalyzed () gooit IOException {List result = analyse (SAMPLE_TEXT, nieuwe StandardAnalyzer ()); assertThat (resultaat, bevat ("baeldung.com", "lucene", "analyzers", "test")); }

Merk op dat de StandardAnalyzer kan URL's en e-mails herkennen.

Het verwijdert ook stopwoorden en zet de gegenereerde tokens in kleine letters.

4.2. StopAnalyzer

De StopAnalyzer bestaat uit LetterTokenizer, LowerCaseFilter, en StopFilter:

@Test openbare leegte whenUseStopAnalyzer_thenAnalyzed () gooit IOException {Lijstresultaat = analyseren (SAMPLE_TEXT, nieuwe StopAnalyzer ()); assertThat (resultaat, bevat ("baeldung", "com", "lucene", "analyzers", "test")); }

In dit voorbeeld is de LetterTokenizer splitst tekst in niet-lettertekens, terwijl de StopFilter verwijdert stopwoorden uit de tokenlijst.

In tegenstelling tot de StandardAnalyzer, StopAnalyzer kan URL's niet herkennen.

4.3. SimpleAnalyzer

SimpleAnalyzer bestaat uit LetterTokenizer en een LowerCaseFilter:

@Test openbare leegte whenUseSimpleAnalyzer_thenAnalyzed () gooit IOException {List result = analyse (SAMPLE_TEXT, nieuwe SimpleAnalyzer ()); assertThat (resultaat, bevat ("dit", "is", "baeldung", "com", "lucene", "analyzers", "test")); }

Hier de SimpleAnalyzer heeft geen stopwoorden verwijderd. Het herkent ook geen URL's.

4.4. WhitespaceAnalyzer

De WhitespaceAnalyzer gebruikt alleen een WhitespaceTokenizer die tekst opsplitst in witruimtetekens:

@Test openbare leegte whenUseWhiteSpaceAnalyzer_thenAnalyzed () gooit IOException {Lijstresultaat = analyseren (SAMPLE_TEXT, nieuwe WhitespaceAnalyzer ()); assertThat (resultaat, bevat ("Dit", "is", "baeldung.com", "Lucene", "Analyzers", "test")); }

4.5. TrefwoordAnalyzer

De TrefwoordAnalyzer tokeniseert invoer in een enkel token:

@Test openbare leegte whenUseKeywordAnalyzer_thenAnalyzed () gooit IOException {Lijstresultaat = analyseren (SAMPLE_TEXT, nieuwe KeywordAnalyzer ()); assertThat (resultaat, bevat ("Dit is baeldung.com Lucene Analyzers-test")); }

De TrefwoordAnalyzer is handig voor velden zoals ID's en postcode.

4.6. Taalanalysatoren

Er zijn ook speciale analysers voor verschillende talen, zoals EnglishAnalyzer, Franse Analyzer, en Spaanse Analyzer:

@Test openbare leegte whenUseEnglishAnalyzer_thenAnalyzed () gooit IOException {Lijstresultaat = analyseren (SAMPLE_TEXT, nieuwe EnglishAnalyzer ()); assertThat (resultaat, bevat ("baeldung.com", "lucen", "analyz", "test")); }

Hier gebruiken we de EnglishAnalyzer Welke bestaat uit StandardTokenizer, StandaardFilter, EnglishPossessiveFilter, LowerCaseFilter, StopFilter, en PorterStemFilter.

5. Aangepaste Analyzer

Laten we vervolgens kijken hoe we onze aangepaste analysator kunnen bouwen. We bouwen dezelfde aangepaste analyser op twee verschillende manieren.

In het eerste voorbeeld we zullen de CustomAnalyzer builder om onze analyzer samen te stellen met vooraf gedefinieerde tokenizers en filters:

@Test public void whenUseCustomAnalyzerBuilder_thenAnalyzed () gooit IOException {Analyzer analyzer = CustomAnalyzer.builder () .withTokenizer ("standaard") .addTokenFilter ("kleine letters") .addTokenFilter ("stop") .addTokenFilter ("porterstem"). ("Porterstem"). ("Porterstem"). ("Porterstem"). hoofdlettergebruik ") .build (); Lijstresultaat = analyseren (SAMPLE_TEXT, analysator); assertThat (resultaat, bevat ("Baeldung.com", "Lucen", "Analyz", "Test")); }

Onze analyser lijkt erg op EnglishAnalyzer, maar in plaats daarvan worden de tokens met een hoofdletter geschreven.

In het tweede voorbeeld we bouwen dezelfde analyzer door de extensie Analyzer abstracte klasse en het overschrijven van de createComponents () methode:

openbare klasse MyCustomAnalyzer breidt Analyzer uit {@Override beschermde TokenStreamComponents createComponents (String fieldName) {StandardTokenizer src = nieuwe StandardTokenizer (); TokenStream-resultaat = nieuw StandardFilter (src); result = nieuwe LowerCaseFilter (resultaat); result = nieuw StopFilter (resultaat, StandardAnalyzer.STOP_WORDS_SET); result = nieuwe PorterStemFilter (resultaat); result = new CapitalizationFilter (resultaat); retourneer nieuwe TokenStreamComponents (src, resultaat); }}

We kunnen ook onze aangepaste tokenizer of filter maken en deze indien nodig toevoegen aan onze aangepaste analysator.

Laten we nu onze aangepaste analysator in actie zien - we zullen gebruiken InMemoryLuceneIndex in dit voorbeeld:

@Test openbare ongeldig gegevenTermQuery_whenUseCustomAnalyzer_thenCorrect () {InMemoryLuceneIndex luceneIndex = nieuwe InMemoryLuceneIndex (nieuwe RAMDirectory (), nieuwe MyCustomAnalyzer ()); luceneIndex.indexDocument ("introductie", "introductie tot lucene"); luceneIndex.indexDocument ("analyzers", "guide to lucene analyzers"); Queryquery = nieuwe TermQuery (nieuwe term ("body", "Introduct")); Lijst documenten = luceneIndex.searchIndex (query); assertEquals (1, documents.size ()); }

6. PerFieldAnalyzerWrapper

Tenslotte, we kunnen verschillende analyzers aan verschillende velden toewijzen met PerFieldAnalyzerWrapper.

Eerst moeten we onze analyzerMap om elke analysator toe te wijzen aan een specifiek veld:

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

We hebben de "titel" toegewezen aan onze aangepaste analyzer en de "body" aan de EnglishAnalyzer.

Laten we vervolgens onze PerFieldAnalyzerWrapper door het analyzerMap en een standaard Analyzer:

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

Laten we het nu testen:

@Test openbare ongeldig gegevenTermQuery_whenUsePerFieldAnalyzerWrapper_thenCorrect () {InMemoryLuceneIndex luceneIndex = nieuwe InMemoryLuceneIndex (nieuwe RAMDirectory (), wrapper); luceneIndex.indexDocument ("introductie", "introductie tot lucene"); luceneIndex.indexDocument ("analyzers", "guide to lucene analyzers"); Queryquery = new TermQuery (new Term ("body", "introduct")); Lijst documenten = luceneIndex.searchIndex (query); assertEquals (1, documents.size ()); query = new TermQuery (new Term ("title", "Introduct")); documents = luceneIndex.searchIndex (zoekopdracht); assertEquals (1, documents.size ()); }

7. Conclusie

We bespraken populaire Lucene Analyzers, hoe je een custom analyzer bouwt en hoe je per veld een andere analyzer gebruikt.

De volledige broncode is te vinden op GitHub.