Analyzer und Tokenizer im Detail verstehen
AI generated
_doc
_index
Elasticsearch · OpenSearch · Analyzer · Volltextsuche
Analyzer und Tokenizer
die Textverarbeitungs-Pipeline hinter jeder Suche verstehen

Jede Volltextsuche in Elasticsearch steht und faellt mit dem Analyzer, der Text beim Indexieren und beim Suchen in vergleichbare Tokens zerlegt. Wer Character Filter, Tokenizer und Token Filter als Pipeline versteht, kann eigene Analyzer bauen und nachvollziehen, warum eine Suche Treffer liefert oder eben nicht.

19 Min. Lesezeit Character Filter · Tokenizer · Token Filter · _analyze API Elasticsearch 8.x · OpenSearch 2.x

1. Was ein Analyzer ist und warum jede Suche einen braucht

Ein Analyzer ist die Komponente in Elasticsearch, die einen Text-String in eine Folge von durchsuchbaren Tokens umwandelt. Ohne Analyzer waere jedes text-Feld nur als exakter String vergleichbar, genau wie ein keyword-Feld, und eine Suche nach einem einzelnen Wort innerhalb eines laengeren Satzes waere unmoeglich. Der Analyzer laeuft zweimal: einmal beim Indexieren eines Dokuments, um die gespeicherten Tokens zu erzeugen, und einmal beim Ausfuehren einer Suchanfrage, um die Suchbegriffe in vergleichbare Tokens umzuwandeln.

Dass eine Suche nach "laufen" ein Dokument mit dem Wort "Laufen" findet, obwohl Gross- und Kleinschreibung unterschiedlich sind, ist keine Magie, sondern das Ergebnis eines Analyzers, der beide Werte auf denselben Token normalisiert. Genauso ist es kein Zufall, wenn eine Suche unerwartet fehlschlaegt, weil Index-Zeit und Such-Zeit unterschiedliche Tokens erzeugt haben. Dieser Artikel zerlegt den Analyzer in seine drei Bausteine und zeigt, wie man das Verhalten gezielt testet, statt zu raten.

2. Die Analyzer-Pipeline: Character Filter, Tokenizer, Token Filter

Ein Analyzer ist keine einzelne Funktion, sondern eine dreistufige Pipeline. Zuerst durchlaeuft der rohe Text null oder mehr Character Filter, die den String vor der Zerlegung veraendern, etwa HTML-Tags entfernen oder bestimmte Zeichen ersetzen. Danach kommt genau ein Tokenizer zum Einsatz, der den bereinigten Text in einzelne Tokens zerlegt, meist an Wortgrenzen. Zuletzt durchlaufen diese Tokens null oder mehr Token Filter, die einzelne Tokens veraendern, entfernen oder hinzufuegen, etwa durch Kleinschreibung, Stoppwort-Entfernung oder Stemming.

Diese Reihenfolge ist fest und nicht vertauschbar: Character Filter arbeiten immer auf dem rohen String, der Tokenizer zerlegt immer genau einmal, und Token Filter arbeiten immer auf der bereits erzeugten Tokenliste. Diese klare Trennung macht die Pipeline vorhersehbar und erlaubt, jeden der drei Bausteine unabhaengig auszutauschen, ohne die anderen beiden zu beeinflussen. Ein Analyzer ist letztlich nichts anderes als eine benannte Kombination aus null oder mehr Character Filtern, genau einem Tokenizer und null oder mehr Token Filtern.


// Pipeline order is always fixed:
// raw text -> char_filter[] -> tokenizer -> token_filter[] -> final tokens

GET /_analyze
{
  "char_filter": ["html_strip"],
  "tokenizer": "standard",
  "filter": ["lowercase", "stop"],
  "text": "<p>The Quick Brown Fox jumps!</p>"
}

// Result tokens roughly: quick, brown, fox, jumps

3. Character Filter: Text vor der Zerlegung bereinigen

Character Filter operieren auf dem unveraenderten Eingabestring, bevor irgendeine Zerlegung stattfindet. Der eingebaute Filter html_strip entfernt HTML-Markup und dekodiert HTML-Entities, was bei Inhalten aus einem CMS oder Rich-Text-Editor haeufig gebraucht wird, damit Tags wie <strong> nicht versehentlich als Teil eines Tokens landen. Der Filter mapping ersetzt konfigurierbare Zeichenfolgen durch andere, etwa um kaufmaennische Sonderzeichen wie "&" durch "und" zu ersetzen, bevor der Tokenizer greift.

Der Filter pattern_replace erlaubt regulaere Ausdruecke fuer komplexere Ersetzungen, etwa das Entfernen von Telefonnummern-Formatierungszeichen vor der Indexierung. Wichtig ist, Character Filter sparsam einzusetzen: Jeder zusaetzliche Filter kostet Rechenzeit bei jedem indexierten Dokument und bei jeder Suchanfrage, und eine zu aggressive Bereinigung kann relevante Information aus dem Text entfernen, bevor der Tokenizer ueberhaupt zum Zug kommt.

4. Tokenizer: Text in Tokens zerlegen

Der Tokenizer ist das Herzstueck jedes Analyzers und in jeder Pipeline genau einmal vorhanden. Der standard-Tokenizer implementiert die Unicode-Text-Segmentierungsregeln und zerlegt Text an Wortgrenzen, wobei er Satzzeichen entfernt, aber Punkte in Abkuerzungen und E-Mail-Adressen sinnvoll behandelt. Fuer die meisten europaeischen Sprachen liefert er brauchbare Ergebnisse ohne weitere Konfiguration.

Der whitespace-Tokenizer zerlegt ausschliesslich an Leerzeichen und behaelt Satzzeichen als Teil der Tokens, was fuer Codebeispiele oder technische Identifier sinnvoll sein kann, bei denen Satzzeichen Bedeutung tragen. Der ngram- und edge_ngram-Tokenizer zerlegen Woerter in ueberlappende Zeichenfolgen fester Laenge und sind die Grundlage fuer Autocomplete- und Teilstring-Suche, weil sie auch mitten im Wort Treffer ermoeglichen, wo ein standard-Tokenizer nur ganze Woerter als Tokens liefert. Der keyword-Tokenizer schliesslich gibt den kompletten Eingabestring als einziges Token zurueck und wird oft in Kombination mit Token Filtern fuer kontrollierte Normalisierung eingesetzt, wenn keine echte Wortzerlegung gewuenscht ist.


GET /_analyze
{
  "tokenizer": "edge_ngram",
  "text": "search"
}
// Tokens: s, se, sea, sear, searc, search
// Useful base for autocomplete-style prefix matching

5. Token Filter: Tokens verfeinern und normalisieren

Token Filter arbeiten nach dem Tokenizer und koennen beliebig oft hintereinander geschaltet werden, wobei jeder Filter die Ausgabe des vorherigen als Eingabe erhaelt. Der Filter lowercase ist der mit Abstand haeufigste und sorgt dafuer, dass "Suche" und "suche" auf denselben Token abgebildet werden. Der Filter stop entfernt haeufige Fuellwoerter wie "und", "der", "die" aus dem Token-Strom, um Indexgroesse zu reduzieren und Relevanz-Rauschen zu vermeiden, sollte aber mit Bedacht eingesetzt werden, weil Stoppwoerter in manchen Phrasensuchen semantisch wichtig sind.

Stemming-Filter wie stemmer mit Sprachkonfiguration reduzieren Woerter auf ihren Wortstamm, sodass "laufend", "laeuft" und "gelaufen" auf einen gemeinsamen Token abgebildet werden koennen und eine Suche nach einer Form auch die anderen findet. Der Filter synonym erweitert Tokens um konfigurierte Synonyme, sodass eine Suche nach "Laptop" auch Dokumente mit "Notebook" findet. Diese Filter erhoehen die Trefferquote spuerbar, koennen aber bei zu aggressiver Konfiguration auch ungewollte Treffer erzeugen, weshalb Tests mit realen Suchbegriffen unverzichtbar sind.

6. Der Standard-Analyzer und seine Grenzen

Ohne explizite Konfiguration verwendet Elasticsearch fuer jedes text-Feld den standard-Analyzer, der aus dem standard-Tokenizer und dem lowercase-Token-Filter besteht, ohne Character Filter und ohne Stemming. Er eignet sich fuer generischen, mehrsprachigen Text ordentlich, ist aber fuer spezialisierte Anwendungsfaelle selten optimal. Deutsche Komposita wie "Bahnhofsvorplatz" werden zum Beispiel als ein einziges Token behandelt, sodass eine Suche nach "Bahnhof" keinen Treffer liefert, obwohl das Wort im Kontext sinnvoll waere.

Fuer solche Faelle bietet Elasticsearch sprachspezifische, eingebaute Analyzer wie german, die zusaetzliche Token Filter fuer Normalisierung, Stemming und in manchen Faellen Kompositazerlegung mitbringen. Der Wechsel vom standard-Analyzer zu einem sprachspezifischen Analyzer ist oft der schnellste Hebel, um die Suchqualitaet in einer bestimmten Sprache spuerbar zu verbessern, ohne selbst eine Pipeline zusammenzustellen.

7. Einen eigenen Analyzer zusammensetzen

Wenn weder der standard-Analyzer noch die eingebauten sprachspezifischen Varianten passen, laesst sich ein Custom Analyzer im Index-Mapping frei aus den drei Bausteinen zusammensetzen. Das ist der Punkt, an dem Elasticsearch seine volle Flexibilitaet zeigt: Ein Team kann etwa einen Analyzer bauen, der HTML-Tags entfernt, mit dem standard-Tokenizer zerlegt, in Kleinbuchstaben normalisiert, deutsche Stoppwoerter entfernt und anschliessend Stemming anwendet, alles in einer einzigen benannten Definition.

Wichtig bei eigenen Analyzern ist, sie nicht isoliert, sondern immer im Kontext realer Suchbegriffe zu entwerfen. Ein zu aggressiv konfigurierter Analyzer mit vielen Stemming- und Synonym-Filtern erhoeht zwar die Trefferzahl, senkt aber oft die Praezision, weil zu viele thematisch entfernte Dokumente ebenfalls matchen. Ein guter Ausgangspunkt ist immer, mit dem standard-Analyzer zu beginnen und gezielt einzelne Filter zu ergaenzen, statt von Null an eine komplette Pipeline zu entwerfen.


PUT /articles
{
  "settings": {
    "analysis": {
      "analyzer": {
        "german_content": {
          "type": "custom",
          "char_filter": ["html_strip"],
          "tokenizer": "standard",
          "filter": ["lowercase", "german_stop", "german_normalization", "german_stemmer"]
        }
      },
      "filter": {
        "german_stop": { "type": "stop", "stopwords": "_german_" },
        "german_stemmer": { "type": "stemmer", "language": "light_german" }
      }
    }
  },
  "mappings": {
    "properties": {
      "content": { "type": "text", "analyzer": "german_content" }
    }
  }
}

8. Mit der _analyze-API testen und debuggen

Die _analyze-API ist das wichtigste Werkzeug, um das Verhalten eines Analyzers zu verstehen, bevor er auf produktive Daten angewendet wird. Sie akzeptiert entweder einen benannten, im Index konfigurierten Analyzer oder eine ad-hoc definierte Kombination aus Tokenizer und Filtern und gibt fuer jeden erzeugten Token Position, Startoffset, Endoffset und Typ zurueck. Das macht sichtbar, warum ein bestimmter Suchbegriff matcht oder nicht matcht, ohne ein Testdokument tatsaechlich indexieren zu muessen.

Ein bewaehrter Debugging-Workflow: Zuerst den fraglichen Text gegen den Index-Time-Analyzer laufen lassen und die erzeugten Tokens notieren, dann denselben Test mit dem Suchbegriff gegen den Search-Time-Analyzer wiederholen. Stimmen die beiden Tokenlisten nicht ueberein, liegt genau dort die Ursache eines unerwarteten Suchergebnisses. Dieser Vergleich spart in der Praxis erheblich Zeit gegenueber dem Versuch, das Problem allein durch Query-Anpassungen zu loesen.


# Test a named analyzer configured on an index
curl -s -X GET "https://localhost:9200/articles/_analyze?pretty" \
  -H 'Content-Type: application/json' -u elastic:changeme -d '{
    "analyzer": "german_content",
    "text": "Der Bahnhofsvorplatz wird neu gestaltet"
  }'

# Test an ad-hoc combination without touching the index
curl -s -X GET "https://localhost:9200/_analyze?pretty" \
  -H 'Content-Type: application/json' -u elastic:changeme -d '{
    "tokenizer": "standard",
    "filter": ["lowercase", "asciifolding"],
    "text": "Cafe Muenchen"
  }'

Ein oft uebersehenes Detail: Ein text-Feld kann zwei unterschiedliche Analyzer verwenden, einen fuer das Indexieren und einen fuer die Suche, konfiguriert ueber die Parameter analyzer und search_analyzer im Mapping. Standardmaessig wird derselbe Analyzer fuer beide Phasen verwendet, was fuer die meisten Faelle korrekt ist. Es gibt aber legitime Gruende, sie zu trennen, etwa bei Synonym-Erweiterung: Synonyme werden oft nur beim Indexieren angewendet, damit ein Dokument mit "Laptop" auch fuer die Suche nach "Notebook" gefunden wird, ohne dass beim Suchen selbst zusaetzliche, unkontrollierte Erweiterungen entstehen.

Ein haeufiger Fehler entsteht, wenn Index-Time- und Search-Time-Analyzer unbeabsichtigt auseinanderlaufen, etwa weil ein Custom Analyzer nur fuer eine der beiden Phasen aktualisiert wurde. Das Ergebnis sind Suchen, die inkonsistent funktionieren: Manche Dokumente werden gefunden, aehnliche, korrekt indexierte Dokumente aber nicht, ohne dass ein offensichtlicher Fehler im Query auftaucht. Die _analyze-API mit explizitem Analyzer-Namen ist in solchen Faellen das schnellste Mittel, um die Diskrepanz sichtbar zu machen, bevor man in der Query-Logik nach dem Fehler sucht.

Fuer Magento-Betreiber mit dem Elasticsearch-Katalogindex ist relevant, dass die Sprachauswahl im Shop direkt beeinflusst, welcher sprachspezifische Analyzer fuer Produktnamen und Beschreibungen verwendet wird. Ein Shop mit deutschem und englischem Storeview braucht in der Regel unterschiedliche Analyzer-Konfigurationen pro Sprache, sonst wird deutschsprachiger Content mit einem fuer Englisch optimierten Standard-Analyzer verarbeitet und Komposita sowie Umlaute suboptimal behandelt.

Baustein Aufgabe in der Pipeline Anzahl pro Analyzer Beispiel
Character Filter Rohtext vor der Zerlegung bereinigen null oder mehr html_strip, mapping
Tokenizer Text in einzelne Tokens zerlegen genau einer standard, edge_ngram
Token Filter Tokens normalisieren, entfernen, erweitern null oder mehr lowercase, stop, stemmer

Diese Tabelle fasst die Rollenverteilung zusammen: Nur der Tokenizer ist zwingend genau einmal vorhanden, Character Filter und Token Filter sind optional und beliebig oft kombinierbar. Wer einen Analyzer debuggt, sollte immer zuerst pruefen, welcher Tokenizer verwendet wird, weil er die grundlegende Zerlegungslogik bestimmt, auf der alle nachfolgenden Filter aufbauen.

10. Zusammenfassung

Ein Analyzer ist eine feste Pipeline aus Character Filtern, genau einem Tokenizer und Token Filtern, die gemeinsam bestimmen, wie Text beim Indexieren und beim Suchen in vergleichbare Tokens verwandelt wird. Der standard-Analyzer deckt generische Faelle ab, stoesst aber bei sprachspezifischen Anforderungen wie deutschen Komposita an Grenzen, die sprachspezifische Analyzer oder ein selbst zusammengesetzter Custom Analyzer loesen.

Die _analyze-API macht das sonst unsichtbare Verhalten eines Analyzers greifbar und ist das zentrale Werkzeug, um Suchprobleme systematisch statt durch Raten zu loesen. Wer zusaetzlich versteht, dass Index-Time- und Search-Time-Analyzer auseinanderfallen koennen, findet die Ursache inkonsistenter Suchergebnisse deutlich schneller als durch Trial-and-Error an der Query allein.

Analyzer und Tokenizer, das Wichtigste auf einen Blick

Feste Pipeline

Character Filter, genau ein Tokenizer, Token Filter, in dieser Reihenfolge, nicht vertauschbar.

Tokenizer als Herzstueck

standard fuer generischen Text, ngram/edge_ngram fuer Autocomplete, keyword fuer kontrollierte Normalisierung.

Custom Analyzer

Frei aus den drei Bausteinen zusammensetzbar, am besten ausgehend vom standard-Analyzer erweitert.

_analyze API

Zeigt erzeugte Tokens ohne Indexierung, der schnellste Weg, Suchprobleme zu debuggen.

11. FAQ: Analyzer und Tokenizer in Elasticsearch

1Was ist ein Analyzer?
Eine Pipeline aus Character Filtern, einem Tokenizer und Token Filtern, die Text in durchsuchbare Tokens umwandelt. Laeuft beim Indexieren und beim Suchen.
2Tokenizer vs. Token Filter?
Der Tokenizer zerlegt einmalig in Tokens, Token Filter verfeinern danach die bereits erzeugte Tokenliste, beliebig oft kombinierbar.
3Wann Character Filter nutzen?
Wenn Rohtext vor der Zerlegung bereinigt werden muss, etwa html_strip fuer HTML-Tags oder mapping fuer Zeichenersetzung.
4Warum ist standard bei Deutsch schwaecher?
Kein Stemming, keine Kompositazerlegung. Bahnhofsvorplatz bleibt ein Token, eine Suche nach Bahnhof findet es nicht.
5Wie teste ich ohne Indexierung?
Mit der _analyze-API, die erzeugte Tokens direkt anzeigt, ohne dass ein Dokument gespeichert werden muss.
6Was ist search_analyzer?
Ein separat konfigurierbarer Analyzer fuer die Suchphase, waehrend analyzer das Indexieren steuert. Standardmaessig identisch.
7Was macht edge_ngram?
Zerlegt ein Wort in ueberlappende Praefixe fester Laenge, Grundlage fuer Autocomplete mit Praefix-Matching.
8Wann stop-Filter vermeiden?
Bei Phrasensuchen, in denen Fuellwoerter semantisch relevant sind, kann der stop-Filter die Ergebnisqualitaet verschlechtern.
9Wie baue ich einen Custom Analyzer?
Im Settings-Block unter analysis einen Analyzer vom Typ custom mit eigenen char_filter-, tokenizer- und filter-Bausteinen definieren.
10Betrifft das Magento-Produktsuchen?
Ja, die Storeview-Sprache bestimmt den verwendeten Analyzer. Mehrsprachige Shops brauchen meist eigene Konfigurationen pro Sprache.