Eigene OpenSearch-Analyzer für die Magento-Produktsuche konfigurieren
AI generated
M2
di.xml
Magento 2
Eigene OpenSearch-Analyzer für die Magento-Produktsuche
Wenn der Standard-Analyzer bei Artikelnummern und Komposita an seine Grenzen stößt

Magentos Standard-Analyzer für die Produktsuche ist auf englischsprachige Fließtexte optimiert und stößt bei Artikelnummern mit Sonderzeichen sowie bei zusammengesetzten deutschen Wörtern schnell an seine Grenzen. Dieser Artikel zeigt, wie Magento Index-Mappings und Analyzer für OpenSearch tatsächlich aufbaut, wie sich ein eigener Analyzer für solche Sonderfälle registrieren lässt und wie sich dessen Wirkung direkt über die OpenSearch-API prüfen lässt, bevor er produktiv indexiert wird.

10 Min. Lesezeit OpenSearch Analyzer Suche-Mapping Deutsche Komposita

1. Wo der Standard-Analyzer bei Sonderfällen scheitert

Der von Magento standardmäßig verwendete Analyzer kombiniert einen Standard-Tokenizer mit Lowercase-Filter, ASCII-Folding und einem Snowball-Stemmer. Für gewöhnliche Produktnamen und Beschreibungstexte funktioniert diese Kombination gut, bei Artikelnummern mit Bindestrichen, Schrägstrichen oder Punkten liefert sie jedoch oft unbrauchbare Tokens, weil der Tokenizer solche Zeichen als Worttrenner interpretiert.

Ein zweites, häufig unterschätztes Problem betrifft zusammengesetzte deutsche Wörter. Eine Suche nach Gartenschlauch findet ein Produkt mit dem Titel Gartenschlauchhalter oft nicht, weil der Standard-Analyzer das zusammengesetzte Wort als ein einziges, unteilbares Token behandelt und keine sprachspezifische Zerlegung vornimmt. Genau diese beiden Fälle, Sonderzeichen in Artikelnummern und deutsche Komposita, stehen im Fokus dieses Artikels.

Abgegrenzt wird das bewusst von allgemeinem Relevanz-Tuning und Synonymen, die bereits an anderer Stelle behandelt werden. Hier geht es ausschließlich um die Analyzer- und Tokenizer-Ebene, also darum, wie ein Text überhaupt in durchsuchbare Tokens zerlegt wird, bevor Scoring oder Synonyme greifen können.

2. Wie Magento Mapping und Analyzer für den Suchindex aufbaut

Magento generiert die Index-Einstellungen für catalogsearch_fulltext nicht bei jedem Indexer-Lauf händisch neu, sondern liest eine deklarative Konfiguration aus dem Modul Magento_Elasticsearch, die Tokenizer, Filter und Analyzer-Definitionen beschreibt. Diese Konfiguration wird beim Anlegen eines neuen Index als settings-Block an OpenSearch übergeben, zusammen mit dem eigentlichen Feld-Mapping für Attribute wie sku, name oder description.

Entscheidend für eigene Erweiterungen ist, dass diese Analyzer-Konfiguration modular aufgebaut ist und über die üblichen Magento-Merging-Mechanismen zusammengeführt wird, ganz ähnlich wie es von db_schema.xml oder events.xml bekannt ist. Ein eigenes Modul kann also zusätzliche Analyzer, Filter und char_filter deklarieren, ohne den Core-Code des Elasticsearch-Moduls anzufassen.

Wichtig dabei: Eine Änderung an der Analyzer-Konfiguration wird erst nach einem vollständigen Reindex wirksam, weil OpenSearch die Analyzer-Einstellungen eines bestehenden Index nicht nachträglich ändern kann. Magento legt bei jedem Reindex-Lauf ohnehin einen neuen, versionierten Index an und wechselt den Alias erst nach erfolgreichem Abschluss, wodurch dieses Verhalten für Analyzer-Änderungen ideal passt.

3. Eigenen Analyzer über ein Modul registrieren

Ein eigener Analyzer wird über ein schlankes Modul registriert, das lediglich von Magento_Elasticsearch abhängt und keine eigenen Blöcke oder Controller benötigt. Die eigentliche Deklaration erfolgt in einer eigenen es_indexer.xml, die char_filter, filter und analyzer Knoten definiert und beim Modul-Merge zusammen mit den Core-Definitionen zu einem einzigen settings-Objekt zusammengeführt wird.

Der Analyzer-Name muss projektweit eindeutig sein, deshalb empfiehlt sich ein Vendor-Präfix wie mironsoft_sku_analyzer, um Kollisionen mit künftigen Core-Analyzern oder anderen Drittmodulen auszuschließen. Nach einem Reindex lässt sich der neue Analyzer wie jeder eingebaute Analyzer über die OpenSearch-API ansprechen und testen.


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Elasticsearch:etc/es_indexer.xsd">
    <char_filter name="mironsoft_sku_char_filter" type="pattern_replace">
        <pattern><![CDATA[[\/\.]]]></pattern>
        <replacement><![CDATA[_]]></replacement>
    </char_filter>
    <filter name="mironsoft_german_decompounder" type="dictionary_decompounder">
        <word_list_path><![CDATA[analysis/german_compounds.txt]]></word_list_path>
        <min_subword_size><![CDATA[4]]></min_subword_size>
    </filter>
    <analyzer name="mironsoft_sku_analyzer">
        <char_filter><![CDATA[mironsoft_sku_char_filter]]></char_filter>
        <filter><![CDATA[lowercase]]></filter>
        <tokenizer><![CDATA[keyword]]></tokenizer>
    </analyzer>
    <analyzer name="mironsoft_german_analyzer">
        <filter><![CDATA[lowercase,mironsoft_german_decompounder,german_normalization]]></filter>
        <tokenizer><![CDATA[standard]]></tokenizer>
    </analyzer>
</config>

4. Artikelnummern mit Sonderzeichen sauber tokenisieren

Für sku greift üblicherweise ein keyword-Tokenizer, der den gesamten Wert als ein einziges Token behandelt, kombiniert mit einem pattern_replace-Filter, der Trennzeichen wie Schrägstriche oder Punkte durch Unterstriche ersetzt. Dadurch bleibt die Artikelnummer exakt matchbar, während unterschiedliche Schreibweisen wie ABC-123 und ABC/123 auf dasselbe normalisierte Token abgebildet werden.

Wer zusätzlich eine Teilstring-Suche auf Artikelnummern erlauben will, etwa den Fund von ABC-123 bei Eingabe von 123, braucht einen zweiten, edge_ngram-basierten Analyzer für ein separates Suchfeld, da ein reiner Keyword-Analyzer grundsätzlich nur exakte Treffer liefert. Beide Analyzer lassen sich parallel über ein Multi-Field-Mapping demselben Attribut zuordnen.


// OpenSearch _analyze-Aufruf zum Test des SKU-Analyzers
POST /magento2_default_catalogsearch_fulltext/_analyze
{
  "analyzer": "mironsoft_sku_analyzer",
  "text": "ABC-123/DE.v2"
}

// Erwartete Ausgabe (gekürzt)
{
  "tokens": [
    { "token": "abc_123_de_v2", "start_offset": 0, "end_offset": 13, "type": "word" }
  ]
}

5. Deutsche Komposita mit dem Dictionary Decompounder zerlegen

Der dictionary_decompounder-Filter benötigt eine gepflegte Wortliste im Analysis-Verzeichnis des Index, aus der er Teilwörter erkennt. Für Gartenschlauchhalter mit den Einträgen garten, schlauch und halter in der Liste erzeugt der Filter zusätzlich zum Originaltoken die drei Teiltokens, sodass eine Suche nach Gartenschlauch das Produkt trotzdem findet.

Die Wortliste ist der wartungsintensivste Teil dieser Lösung, weil OpenSearch keine automatische morphologische Zerlegung für Deutsch mitbringt wie es Hunspell-Wörterbücher für andere Sprachen tun. In der Praxis bewährt sich eine kategoriespezifische Liste mit den 200 bis 400 häufigsten Fachbegriffen des jeweiligen Sortiments, gepflegt als Textdatei im Analysis-Verzeichnis und über ein Deploy-Skript synchron zu allen Store-Umgebungen gehalten.

Wichtig: Der Decompounder-Analyzer sollte nur auf name und die Suchfelder angewendet werden, nicht auf sku, da eine Zerlegung von Artikelnummern in Teiltokens zu falschen Treffern führen würde. Die Feldzuordnung erfolgt daher pro Attribut getrennt, wie im nächsten Abschnitt gezeigt.


# analysis/german_compounds.txt (Auszug), liegt im Analysis-Verzeichnis des OpenSearch-Datenpfads
garten
schlauch
halter
werkzeug
koffer
akku
schrauber

# Datei muss auf allen OpenSearch-Knoten identisch vorliegen, sonst
# liefert ein Shard andere Tokens als ein anderer.

6. Analyzer gezielt einzelnen Feldern zuweisen

Die Zuordnung eines Analyzers zu einem konkreten Attribut erfolgt über das Feld-Mapping, das Magento parallel zu den Analyzer-Definitionen aufbaut. Ein Plugin auf dem zuständigen FieldProvider erlaubt es, für bestimmte Attribut-Codes den analyzer- beziehungsweise search_analyzer-Wert im generierten Mapping zu überschreiben, statt den globalen Default-Analyzer für alle Textfelder zu verwenden.

Dabei sollte zwischen Index-Analyzer und Search-Analyzer unterschieden werden, denn beide müssen nicht zwingend identisch sein. Für sku ist ein einheitlicher Analyzer in beide Richtungen sinnvoll, für name kann es dagegen helfen, beim Indexieren den Decompounder anzuwenden, bei der Suchanfrage selbst aber einen schlankeren Analyzer ohne Zerlegung zu nutzen, um Mehrdeutigkeiten bei sehr kurzen Suchbegriffen zu vermeiden.


<?php

declare(strict_types=1);

namespace Mironsoft\SearchAnalyzer\Plugin;

use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\Base\Field\FieldTypeConverter;

/**
 * Weist ausgewählten Produktattributen einen eigenen OpenSearch-Analyzer zu,
 * statt den globalen Default-Analyzer für alle Textfelder zu verwenden.
 */
class AssignCustomAnalyzerPlugin
{
    /**
     * Attribut-Code zu Analyzer-Namen, wird nur für explizit gelistete Felder überschrieben.
     *
     * @var array<string, string>
     */
    private const FIELD_ANALYZER_MAP = [
        'sku' => 'mironsoft_sku_analyzer',
        'name' => 'mironsoft_german_analyzer',
    ];

    /**
     * Überschreibt den analyzer-Eintrag im generierten Feld-Mapping für die gelisteten Attribute.
     *
     * @param FieldTypeConverter $subject
     * @param array<string, mixed> $result
     * @param string $attributeCode
     * @return array<string, mixed>
     */
    public function afterConvert(FieldTypeConverter $subject, array $result, string $attributeCode): array
    {
        if (isset(self::FIELD_ANALYZER_MAP[$attributeCode])) {
            $result['analyzer'] = self::FIELD_ANALYZER_MAP[$attributeCode];
        }

        return $result;
    }
}

7. Reindexen und die Analyzer-Wirkung direkt per API prüfen

Nach jeder Änderung an der es_indexer.xml ist ein vollständiger Reindex des Full-Text-Index notwendig, da die Analyzer-Einstellungen nur beim Anlegen eines neuen Index gesetzt werden. Ein einfacher Cache-Flush oder partieller Reindex reicht dafür nicht aus, weshalb sich diese Änderungen zunächst immer in einer Staging-Umgebung testen lassen sollten.

Der schnellste Weg, die tatsächliche Tokenisierung zu prüfen, führt nicht über die Magento-Suchmaske, sondern direkt über die _analyze-API von OpenSearch. Damit lässt sich pro Analyzer und pro Testtext exakt sehen, welche Tokens erzeugt werden, unabhängig davon, ob und wie ein Produkt später tatsächlich gefunden wird.

Erst wenn die Tokens auf API-Ebene wie erwartet aussehen, lohnt sich der nächste Schritt, ein echtes Produkt im Frontend zu suchen. Diese Reihenfolge spart in der Praxis viel Zeit, weil sich Fehler in der Analyzer-Konfiguration sonst erst spät und schwer nachvollziehbar in den Suchergebnissen zeigen.


# Reindex des Suchindex nach Änderung der es_indexer.xml
bin/magento indexer:reindex catalogsearch_fulltext

# Analyzer-Wirkung direkt gegen den lebenden Index prüfen
curl -s -X POST "https://opensearch:9200/magento2_default_catalogsearch_fulltext/_analyze" \
  -H "Content-Type: application/json" \
  -d '{"analyzer": "mironsoft_german_analyzer", "text": "Gartenschlauchhalter"}' | jq .

8. Abgrenzung zu Relevanz-Tuning und Synonymen

Analyzer-Konfiguration und Relevanz-Tuning lösen unterschiedliche Probleme und sollten nicht vermischt werden. Der Analyzer entscheidet, welche Tokens überhaupt entstehen und damit, ob ein Dokument grundsätzlich als Kandidat für eine Suchanfrage infrage kommt. Boosting, Feldgewichtung und Function Scores entscheiden erst danach, in welcher Reihenfolge die gefundenen Kandidaten angezeigt werden.

Ähnlich verhält es sich mit Synonymen, die als eigener Filter in der Analyzer-Kette sitzen, aber ein separates Wartungsproblem darstellen, weil Synonymlisten meist fachlich statt sprachlich gepflegt werden. Ein Decompounder-Filter für Komposita ersetzt keine Synonymliste und umgekehrt, beide Mechanismen ergänzen sich, sollten aber unabhängig voneinander getestet werden, um Ursache und Wirkung bei Suchproblemen sauber trennen zu können.

9. Fallstricke im Produktionsbetrieb

Bei Multi-Store-Setups mit mehreren Sprachen darf der deutsche Analyzer nicht global für alle Store-Views gelten, sonst leidet die Tokenisierung englischer oder französischer Produktdaten. Die Feldzuordnung aus dem FieldProvider-Plugin muss deshalb store- beziehungsweise sprachbewusst implementiert werden, meist über eine Prüfung des aktuellen Store-Codes im Kontext des Reindex-Laufs.

Ein zweiter Fallstrick betrifft die Wortliste des Decompounders, die bei jedem Deploy synchron auf alle OpenSearch-Knoten eines Clusters gelangen muss. Weicht die Datei auch nur in einer Zeile zwischen den Knoten ab, liefern identische Suchanfragen je nach angesprochenem Shard unterschiedliche Ergebnisse, ein Fehlerbild, das sich nur schwer reproduzieren lässt, wenn man den Ursprung nicht kennt.

Schließlich sollte jede Analyzer-Änderung zunächst gegen eine Kopie des Produktivindex in Staging getestet werden, inklusive eines vollständigen Reindex, bevor sie live geschaltet wird. Da ein Analyzer-Wechsel immer einen kompletten Neuaufbau des Index erzwingt, sind ungetestete Änderungen im Produktivbetrieb mit spürbarer Systemlast und im schlechtesten Fall mit einer kurzzeitig unvollständigen Suche verbunden.

Analyzer-Baustein Beispiel Zweck Typischer Einsatz in Magento
char_filter pattern_replace Ersetzt Zeichen vor der Tokenisierung Sonderzeichen in Artikelnummern normalisieren
tokenizer keyword Zerlegt Text in Tokens Exakte Artikelnummer als ein Token behandeln
filter dictionary_decompounder Zerlegt zusammengesetzte Wörter Deutsche Komposita durchsuchbar machen
filter lowercase Normalisiert Groß- und Kleinschreibung Einheitliche Treffer unabhängig von Schreibweise
filter german_normalization Normalisiert Umlaute und ß-Varianten Über und Ueber als gleichwertig behandeln
analyzer edge_ngram-basiert Erzeugt Teiltokens für Präfixsuche Live-Suche nach Teilen einer Artikelnummer

Mironsoft

Magento-Entwicklung, Modul-Beratung und Systemarchitektur

Magento-Projekt, das eine zweite Meinung oder erfahrene Umsetzung braucht?

Wir entwickeln individuelle Magento-Module, beraten bei Architekturentscheidungen und übernehmen komplexe Umsetzungen, von der Service-Contract-Planung bis zum produktionsreifen Deployment.

Architektur-Beratung

Modul- und Systemarchitektur vor der Umsetzung fundiert durchdenken lassen.

Custom-Modul-Entwicklung

Individuelle Magento-Module nach Best Practices sauber umsetzen.

Code-Review & Audit

Bestehende Module auf Performance, Sicherheit und Wartbarkeit prüfen lassen.

10. Zusammenfassung

OpenSearch-Analyzer

Mechanismus

Eigene Module deklarieren zusätzliche char_filter, filter und analyzer Knoten, die mit den Core-Definitionen zusammengeführt werden.

Artikelnummern

Ein keyword-Tokenizer mit pattern_replace-Filter normalisiert Sonderzeichen, ohne die exakte Suchbarkeit zu verlieren.

Komposita

Der dictionary_decompounder-Filter zerlegt zusammengesetzte deutsche Wörter anhand einer gepflegten Wortliste.

Test

Die _analyze-API von OpenSearch prüft die Tokenisierung direkt, unabhängig von der Magento-Suchmaske.

11. FAQ: OpenSearch-Analyzer

1Wird ein eigener Analyzer sofort nach dem Speichern der es_indexer.xml wirksam?
Nein, erst nach einem vollständigen Reindex von catalogsearch_fulltext, weil OpenSearch Analyzer-Einstellungen nur beim Anlegen eines neuen Index setzt, nicht nachträglich.
2Kann ich die Analyzer-Wirkung testen, ohne die Produktsuche im Frontend aufzurufen?
Ja, die _analyze-API von OpenSearch zeigt die erzeugten Tokens direkt an, unabhängig von Scoring, Relevanz oder Frontend-Anzeige.
3Warum findet die Suche Gartenschlauch nicht im Produkt Gartenschlauchhalter?
Der Standard-Analyzer behandelt das zusammengesetzte Wort als ein Token, ein dictionary_decompounder-Filter mit passender Wortliste löst dieses Problem.
4Muss der SKU-Analyzer auch Umlaute normalisieren?
In der Regel nicht, da Artikelnummern meist keine Umlaute enthalten, wichtiger ist die Normalisierung von Trennzeichen wie Schrägstrich und Punkt.
5Wie pflege ich die Wortliste des Decompounders für ein wachsendes Sortiment?
Als Textdatei im Analysis-Verzeichnis, versioniert im Deploy-Prozess und identisch auf allen OpenSearch-Knoten, meist beschränkt auf die häufigsten Fachbegriffe.
6Sollte Index-Analyzer und Search-Analyzer immer identisch sein?
Nicht zwingend, für Artikelnummern ist Einheitlichkeit sinnvoll, für Produktnamen kann ein schlankerer Search-Analyzer Mehrdeutigkeiten bei kurzen Suchbegriffen vermeiden.
7Funktioniert der Decompounder-Filter automatisch für alle Sprachen?
Nein, die Wortliste ist sprachspezifisch, für andere Sprachen wird entweder eine eigene Liste oder ein anderer Mechanismus wie Hunspell benötigt.
8Was passiert, wenn die Wortliste zwischen OpenSearch-Knoten eines Clusters abweicht?
Identische Suchanfragen können je nach angesprochenem Shard unterschiedliche Ergebnisse liefern, deshalb muss die Datei auf allen Knoten synchron gehalten werden.
9Wie weise ich einen Analyzer nur bestimmten Attributen statt global zu?
Über ein Plugin auf dem zuständigen FieldProvider, das im generierten Mapping den analyzer-Wert für gelistete Attribut-Codes gezielt überschreibt.
10Ersetzt ein eigener Analyzer die Synonym-Konfiguration von Magento?
Nein, beide Mechanismen ergänzen sich, ein Analyzer entscheidet über die Tokenisierung, Synonyme erweitern die Trefferliste um fachlich gleichwertige Begriffe.