Search Templates für wiederverwendbare Queries in Elasticsearch einsetzen
AI generated
_doc
_index
Elasticsearch · Search Templates
Search Templates für wiederverwendbare Queries einsetzen
Query-Logik von Parametern trennen mit Mustache-Templates

Wird die vollständige Elasticsearch Query DSL direkt im Anwendungscode zusammengebaut, verteilt sich Suchlogik über viele Stellen der Codebasis und jede Anpassung an einer zentralen Query erfordert Änderungen an mehreren Orten gleichzeitig. Search Templates lösen dieses Problem, indem sie eine Mustache-basierte Query-Vorlage einmal zentral in Elasticsearch hinterlegen und der Anwendungscode anschließend nur noch benannte Parameter übergibt, ohne selbst eine Zeile Query-DSL zu kennen. Damit wandert die eigentliche Suchlogik dorthin, wo sie technisch verwaltet werden sollte, und Anwendungsentwickler arbeiten mit einer stabilen, klar dokumentierten Schnittstelle. Wie Search Templates aufgebaut sind, welche Vorteile das für die Zusammenarbeit zwischen Suchteam und Anwendungsteam bringt und wie eine parametrisierte Produktsuche damit konkret aussieht, zeigt dieser Artikel.

11 Min. Lesezeit Search Templates · Mustache _scripts API · Parametrisierung

1. Das Grundproblem: verstreute Query-Logik im Anwendungscode

In vielen gewachsenen Anwendungen findet sich dieselbe oder eine sehr ähnliche Query-DSL-Struktur mehrfach im Code wieder, einmal für die Produktsuche im Frontend, einmal für einen internen Suchdienst und einmal für einen Batch-Export, jeweils mit kleinen Abweichungen. Ändert sich die zugrunde liegende Relevanzstrategie, etwa weil ein zusätzliches Boosting für aktuelle Angebote eingeführt wird, müssen alle diese Stellen einzeln gefunden und konsistent angepasst werden, was in der Praxis regelmäßig zu Inkonsistenzen führt.

Search Templates verschieben die eigentliche Query-Struktur aus dem Anwendungscode in eine zentral in Elasticsearch verwaltete Vorlage. Die Anwendung ruft diese Vorlage über ihren Namen auf und übergibt lediglich die konkreten Suchparameter, während die komplette Struktur der Query, inklusive Boosting-Regeln, Filtern und Sortierung, an einer einzigen Stelle gepflegt wird.

2. Mustache-Syntax: wie Platzhalter in der Query DSL funktionieren

Ein Search Template ist im Kern eine reguläre Query-DSL-Struktur, in der einzelne Werte durch Mustache-Platzhalter wie {{suchbegriff}} ersetzt werden. Beim Ausführen des Templates ersetzt Elasticsearch jeden Platzhalter durch den übergebenen Parameterwert und wertet die daraus entstandene, vollständige Query genau wie eine normale Suchanfrage aus. Mustache unterstützt dabei auch bedingte Blöcke über {{#parameter}}...{{/parameter}}, die einen Query-Bestandteil nur einfügen, wenn der entsprechende Parameter tatsächlich übergeben wurde.

Diese bedingten Blöcke sind besonders wertvoll für optionale Filter: Ein Preisfilter soll nur dann in die Query eingebaut werden, wenn der Nutzer tatsächlich eine Preisspanne ausgewählt hat, andernfalls soll die Query ohne diesen Filterbestandteil laufen. Ohne Mustache-Bedingungen müsste die Anwendung selbst mehrere Varianten der Query zusammenbauen, mit Mustache genügt ein einziges Template für alle Kombinationen gesetzter und nicht gesetzter Parameter.

3. Ein Search Template über die _scripts-API anlegen

Search Templates werden über die _scripts-API gespeichert, dieselbe API, die auch für andere gespeicherte Skripte verwendet wird. Jedes Template erhält einen eindeutigen Namen, unter dem es später referenziert wird, und einen source-Block mit der eigentlichen Query-DSL-Struktur inklusive Mustache-Platzhaltern. Optional lässt sich auch ein params-Block mit Standardwerten hinterlegen, der greift, sobald die Anwendung einen bestimmten Parameter beim Aufruf nicht übergibt.

Diese zentrale Speicherung hat einen praktischen Nebeneffekt: Eine Änderung am Template wirkt sich sofort auf alle Anwendungen aus, die dieses Template referenzieren, ohne dass irgendeine dieser Anwendungen neu deployt werden müsste. Für Relevanz-Tuning, das häufiger iteriert wird als der eigentliche Anwendungscode, ist das ein erheblicher Geschwindigkeitsvorteil.


PUT _scripts/produktsuche_standard
{
  "script": {
    "lang": "mustache",
    "source": {
      "query": {
        "bool": {
          "must": [
            { "multi_match": { "query": "{{suchbegriff}}", "fields": ["name^3", "beschreibung"] } }
          ],
          "filter": [
            {{#kategorie}}{ "term": { "kategorie": "{{kategorie}}" } },{{/kategorie}}
            { "range": { "preis": { "gte": "{{preis_min}}{{^preis_min}}0{{/preis_min}}", "lte": "{{preis_max}}{{^preis_max}}100000{{/preis_max}}" } } }
          ]
        }
      },
      "size": "{{anzahl}}{{^anzahl}}20{{/anzahl}}"
    },
    "params": { "anzahl": 20 }
  }
}

4. Ein Search Template ausführen

Ausgeführt wird ein gespeichertes Template über den Endpunkt _search/template, wobei die Anwendung lediglich den id-Verweis auf das gespeicherte Template und ein params-Objekt mit den konkreten Werten übergibt. Die Antwort entspricht exakt der Antwort einer regulären Suchanfrage, sodass sich vorhandener Antwort-Verarbeitungscode ohne Anpassung weiterverwenden lässt.

Für die lokale Entwicklung und zum Debugging eignet sich der Endpunkt _render/template, der ein Template mit gegebenen Parametern lediglich auflöst und die daraus entstehende, vollständige Query DSL zurückliefert, ohne tatsächlich eine Suche auszuführen. Damit lässt sich schnell prüfen, ob ein Template mit bestimmten Parametern die erwartete Query erzeugt, bevor man es produktiv gegen den Index laufen lässt.


GET /produkte/_search/template
{
  "id": "produktsuche_standard",
  "params": {
    "suchbegriff": "akkuschrauber",
    "kategorie": "werkzeuge",
    "preis_max": 89.90
  }
}

5. Vorteile für Anwendungsentwickler: keine Query-DSL im Anwendungscode

Für Teams, die eine Suchschnittstelle für andere Anwendungsteams bereitstellen, bedeutet ein Search Template eine klare Verantwortungstrennung: Das Such- oder Datenteam pflegt Relevanz, Boosting und Filterlogik zentral im Template, während Anwendungsentwickler nur eine benannte, dokumentierte Parameterliste kennen müssen, etwa Suchbegriff, Kategorie und Preisspanne. Änderungen an der Relevanzstrategie erfordern damit keine Abstimmung mit jedem einzelnen Anwendungsteam mehr, solange sich die Parameterschnittstelle nicht ändert.

Das reduziert auch das Risiko fehlerhafter Query-DSL-Konstruktion in Anwendungscode, der typischerweise nicht auf Elasticsearch-Query-Syntax spezialisiert ist. Statt verschachtelter bool-Strukturen im Anwendungscode zu debuggen, reicht ein Blick in das zentrale Template, das von den Personen gepflegt wird, die sich mit der Query DSL tatsächlich auskennen.

6. Versionierung und kontrollierte Änderungen an Templates

Da Änderungen an einem Search Template sofort und ohne Deployment für alle aufrufenden Anwendungen wirksam werden, empfiehlt sich eine bewusste Versionierungsstrategie über den Template-Namen selbst, etwa produktsuche_v2 statt einer direkten Überschreibung von produktsuche_standard. So können neue Anwendungsversionen gezielt auf die neue Template-Version umschalten, während bestehende Aufrufer unverändert weiterarbeiten, bis sie explizit migriert werden.

Für kontrollierte Rollouts eignet sich außerdem ein A/B-Testing-Ansatz, bei dem ein Teil des Traffics testweise gegen ein neues Template geleitet wird, während die Mehrheit weiterhin das bewährte Template nutzt. Da beide Templates unabhängig in _scripts gespeichert sind, lässt sich dieser Ansatz ohne Anwendungscode-Änderung rein über die aufgerufene Template-ID steuern.

7. Performance: Kompilierung und Caching von Templates

Elasticsearch kompiliert ein gespeichertes Template beim ersten Aufruf und hält die kompilierte Form in einem internen Skript-Cache vor, sodass wiederholte Aufrufe desselben Templates keine erneute Mustache-Kompilierung erfordern. Der eigentliche Ausführungsaufwand eines Search Templates unterscheidet sich dadurch praktisch nicht von einer direkt formulierten, äquivalenten Query, der Zusatzaufwand beschränkt sich auf die einmalige Parametersubstitution pro Aufruf.

Bei sehr komplexen Templates mit vielen bedingten Blöcken und tief verschachtelter Logik lohnt sich dennoch ein Blick auf die Größe des Skript-Caches, insbesondere wenn viele unterschiedliche Templates parallel im Einsatz sind. Der Cache lässt sich über script.cache.max_size anpassen, falls häufig genutzte Templates aus dem Cache verdrängt werden und dadurch wiederholt neu kompiliert werden müssen.

8. Praxisbeispiel: parametrisierte Produktsuche mit Standardwerten

Im gezeigten Template für die Produktsuche wird der Suchbegriff verpflichtend über multi_match gegen Name und Beschreibung geprüft, während Kategorie und Preisspanne optional bleiben. Fehlt der Preisfilter komplett, greifen über die Mustache-Negationssyntax {{^preis_min}} sinnvolle Standardwerte, sodass die Query auch ohne explizite Preisangabe eine gültige, sinnvolle Bereichsbedingung enthält, statt mit einem leeren oder fehlerhaften Filter zu scheitern.

Die Anwendung selbst muss lediglich die vom Nutzer eingegebenen Werte als Parameter durchreichen, ohne zu wissen, dass im Hintergrund eine bool-Query mit multi_match, bedingtem term-Filter und range-Filter aufgebaut wird. Diese Trennung bleibt auch dann stabil, wenn das Suchteam später etwa ein zusätzliches Function-Score-Boosting für Lagerbestand einbaut, solange sich die Parameterschnittstelle nicht ändert.

9. Fallstricke und Empfehlungen für den produktiven Einsatz

Ein häufiger Fehler ist, Parameter ungeprüft und ohne Escaping in ein Template einzusetzen, insbesondere bei Freitextfeldern, die theoretisch Mustache-Sonderzeichen enthalten könnten. Elasticsearch escaped Parameterwerte innerhalb von Mustache-Ausdrücken standardmäßig korrekt, problematisch wird es nur, wenn Parameter versehentlich direkt als Rohquery statt als Wert eingesetzt werden, was die Grenze zwischen Parametrisierung und potenzieller Query-Injection verwischen kann.

Empfehlenswert ist außerdem, jedes produktive Template mit einer kleinen Testsuite aus _render/template-Aufrufen abzusichern, die typische und Grenzfälle der Parameterkombination abdeckt, etwa fehlende optionale Parameter, extreme Preisspannen oder leere Suchbegriffe. So lassen sich Regressionen bei Template-Änderungen frühzeitig erkennen, bevor sie produktiv bei echten Suchanfragen auffallen.

Aspekt Query DSL im Anwendungscode Search Template Praxisrelevanz
Pflegeort der Query-Logik Verteilt über Codebasen Zentral in _scripts Templates verhindern Inkonsistenzen
Deployment bei Änderungen Neues Anwendungsdeployment nötig Sofort wirksam ohne Deployment Schnellere Relevanz-Iteration
Fachwissen im Anwendungscode Query-DSL-Kenntnis erforderlich Nur benannte Parameter nötig Klare Trennung der Verantwortung
Debugging Über Anwendungslogs Über _render/template direkt prüfbar Schnellere Fehlersuche bei Templates
Optionale Filter Manuelle Fallunterscheidung im Code Mustache-Bedingungsblöcke Ein Template für alle Parameterkombinationen

Mironsoft

Suchindex-Setup, Relevanz-Tuning und Magento-Suche

Magento-Suche, die die falschen Produkte zuerst zeigt?

Wir richten Elasticsearch oder OpenSearch für Magento sauber ein, tunen Relevanz und Facetten auf das tatsächliche Sortiment und optimieren Indexierungsprozesse für große Kataloge.

Relevanz-Tuning

Suchergebnisse und Facetten auf die tatsächlichen Kundenbedürfnisse abstimmen.

Such-Migration

Umstieg von Solr oder MySQL-Suche auf Elasticsearch/OpenSearch sauber begleiten.

Index-Performance

Indexierungsprozesse für große Kataloge zuverlässig und performant gestalten.

10. Zusammenfassung

Search Templates: Das Wichtigste auf einen Blick

Grundprinzip

Search Templates trennen die Mustache-basierte Query-DSL-Struktur von den konkreten Suchparametern, die eine Anwendung nur noch benannt übergibt.

Verwaltung

Templates werden über die _scripts-API zentral gespeichert und über _search/template mit Parametern ausgeführt, ohne Anwendungscode-Änderung bei Query-Anpassungen.

Vorteil für Teams

Anwendungsentwickler kennen nur eine dokumentierte Parameterschnittstelle, während das Suchteam Relevanz und Filterlogik unabhängig weiterentwickelt.

Praxisbeispiel

Eine parametrisierte Produktsuche mit optionalem Kategorie- und Preisfilter zeigt, wie Mustache-Bedingungsblöcke ein einziges Template für alle Parameterkombinationen tragfähig machen.

11. FAQ: Search Templates: Das Wichtigste auf einen Blick

1Was ist ein Search Template in Elasticsearch?
Eine zentral gespeicherte, Mustache-basierte Query-DSL-Vorlage, in der einzelne Werte durch Platzhalter ersetzt werden und die über einen Namen mit konkreten Parametern aufgerufen wird.
2Wo werden Search Templates gespeichert?
Über die _scripts-API, dieselbe API, die auch für andere gespeicherte Skripte in Elasticsearch verwendet wird, mit lang auf mustache gesetzt.
3Wie führt man ein gespeichertes Search Template aus?
Über den Endpunkt _search/template mit der id des gespeicherten Templates und einem params-Objekt, das die konkreten Werte für die Platzhalter enthält.
4Welchen Vorteil bringen Search Templates für Anwendungsentwickler?
Sie müssen keine Query-DSL-Details kennen, sondern arbeiten nur mit einer benannten, dokumentierten Parameterschnittstelle, während die eigentliche Query-Logik zentral gepflegt wird.
5Wie lassen sich optionale Filter in einem Template abbilden?
Über Mustache-Bedingungsblöcke wie {{#kategorie}}...{{/kategorie}}, die einen Query-Bestandteil nur dann einfügen, wenn der entsprechende Parameter tatsächlich übergeben wurde.
6Wie lässt sich ein Template debuggen, ohne eine echte Suche auszulösen?
Über den Endpunkt _render/template, der ein Template mit gegebenen Parametern nur auflöst und die entstehende Query DSL zurückliefert, ohne tatsächlich zu suchen.
7Wirken sich Änderungen an einem Template sofort auf alle Anwendungen aus?
Ja, sobald ein Template über die _scripts-API aktualisiert wird, greifen die Änderungen bei jedem folgenden Aufruf, ohne dass Anwendungscode neu deployt werden muss.
8Warum sollte man Templates versionieren statt direkt zu überschreiben?
Weil eine Überschreibung sofort alle aufrufenden Anwendungen betrifft. Ein eigener Name pro Version erlaubt einen kontrollierten Rollout, während bestehende Aufrufer unverändert weiterarbeiten.
9Verursachen Search Templates zusätzlichen Performance-Overhead?
Nur minimal, Elasticsearch kompiliert Templates einmalig und hält sie im Skript-Cache vor, der Ausführungsaufwand entspricht danach im Wesentlichen einer direkt formulierten Query.
10Worauf sollte man beim produktiven Einsatz von Templates achten?
Auf korrektes Escaping von Parameterwerten sowie eine Testsuite aus _render/template-Aufrufen, die typische und Grenzfälle der Parameterkombination vor jedem produktiven Rollout absichert.