Inhaltsverzeichnis
Verbessern Sie Ihre Shopware Suche mit Elasticsearch
Viele Shop-Besitzer sind unzufrieden mit der Standard-Suchfunktionalität von Shopware im Frontend. Die Geschwindigkeit der Suchergebnisse ist bei einigen Begriffskombinationen problematisch, und die Ergebnisse sind manchmal nicht nützlich für bestimmte Suchmuster von Kunden. Darüber hinaus kann die Gesamtleistung des Shops, insbesondere bei einer großen Anzahl von Produkten, mit Elasticsearch erheblich verbessert werden. Während es keinen Zweifel daran gibt, dass Elasticsearch die Leistung verbessert, habe ich keine genauen Messungen für die Anzahl der Produkte, bei denen Elasticsearch unverzichtbar wird.
Ich plane, Messungen durchzuführen, um zu sehen, wie sich der Shop mit unterschiedlichen Produktmengen verhält, und werde diesen Blog aktualisieren, sobald dies geschehen ist. Nach meiner Erfahrung benötigen Shops mit mehr als 50.000 Produkten unbedingt Elasticsearch. Es war auffällig, dass der Shop extrem langsam war, wenn die Warteschlange mit Indexierungsmeldungen voll war, aber nach dem Wechsel zu Elasticsearch war dieses Verhalten nicht mehr reproduzierbar.
Ob Sie zu Elasticsearch wechseln oder ein Plugin erstellen möchten, das Elasticsearch-Abfragen an Ihre Bedürfnisse anpasst, Sie werden wahrscheinlich eine lokale Umgebung für Tests einrichten müssen, bevor Sie bedeutende Änderungen an einem produktiven Shop vornehmen.
Bevor wir fortfahren, ist es erwähnenswert, dass dieser Blog Elasticsearch selbst nicht erklärt, aber Sie sollten dennoch folgen können.
Lokale Umgebung vorbereiten
Als ersten Schritt, wenn Sie Elasticsearch für einen bestimmten Shop testen möchten, überprüfen Sie die Elasticsearch-Version auf dem Server. Bei Timmehosting können Sie beispielsweise Elasticsearch ganz einfach aktivieren/deaktivieren (localhost:9200). Hier ist der Link.
Wenn Elasticsearch aktiv ist und Sie Zugriff auf den Server haben, können Sie die Version über die Konsole überprüfen:
curl -XGET "localhost:9200"
Sie erhalten eine Antwort, die so aussieht:
Eine Übersicht über die Elasticsearch-Version, Nodes, Indizes, Action Buttons und die Konsole finden Sie auch im Elasticsearch-Tab eines großartigen kostenlosen Plugins von Friends Of Shopware: Frosh Tools.
Jetzt wissen wir, welche Version wir in unserer lokalen Umgebung installieren möchten. Wenn Tests zeigen, dass eine Version besser ist als eine andere oder wenn eine höhere Version von Shopware benötigt wird, können wir natürlich die Elasticsearch-Version auf dem Server aktualisieren.
Unsere Docker-Umgebung wird drei Container haben: SW6.6, Elasticsearch und Kibana.
Die docker-compose.yaml
sieht so aus:
Für den Shopware-Container verwende ich das Dev-Image von dockware und die offiziellen Images für Elasticsearch und Kibana. Beachten Sie, dass die Versionen von Elasticsearch und Kibana übereinstimmen müssen.
Um den vorherigen Befehl lokal auszuführen, beachten Sie, dass unser Container "es" heißt, also lautet der Befehl:
CURL -XGET "es:9200"
Von nun an werden wir jedoch keine CURL-Anfragen mehr schreiben, da wir die Kibana Dev Tools unter http://localhost:5601/app/dev_tools#/console
haben, die viel benutzerfreundlicher sind.
Die erste Abfrage wäre, um unsere Indizes zu sehen:
GET _cat/indices?v
_cat
(Kompakter und ausgerichteter Text) ist eine API, die Daten in einem für Menschen lesbaren Format ausgibt.indices
teilt Elasticsearch mit, dass wir unsere Indizes sehen möchten.?v
ist ein ausführlicher Parameter, der eine Kopfzeile über die Spalten bereitstellt, die beschreibt, was die Spalten anzeigen (health, status, usw.).
Zu Beginn sind keine dieser aufgelisteten Indizes nützlich; sie sind nur die Standardeinstellungen von Kibana und Elasticsearch. Um einen Index zu erstellen, der nützliche Daten über eine Entität (wie Produkte) enthält, müssen wir Shopware mit Elasticsearch verbinden.
Shopware hat bereits eine großartige Dokumentation hier, daher werde ich es einfach halten und meine Beispielkonfiguration zeigen.
Die Einstellungen der .env
-Datei sind ziemlich selbsterklärend, aber es sollte erwähnt werden, dass OPENSEARCH_URL
es:9200
ist, da dies der Name meines Containers ist. In einem echten Shop wird dies anders sein; zum Beispiel wäre es bei Timmehosting localhost:9200
. Die SHOPWARE_ES_INDEXING_BATCH_SIZE
ist standardmäßig auf 100 eingestellt, aber aus persönlicher Vorliebe ändere ich sie immer auf 500.
Änderungen an elasticsearch.yaml
sind optional, aber es ist erwähnenswert, dass standardmäßig number_of_shards
und number_of_replicas
auf 3 gesetzt sind. Es gibt viele konfigurierbare Optionen in elasticsearch.yaml
, abhängig von Ihrer Vertrautheit mit Elasticsearch. Optionen und Standardkonfigurationen finden Sie unter vendor/shopware/elasticsearch/Resources/config/packages/elasticsearch.yaml
.
Die lokale Umgebung ist jetzt vorbereitet. Lassen Sie uns im nächsten Abschnitt tiefer eintauchen.
Befehle, Produktindex & Wichtige Funktionen
Als ersten Schritt werde ich xDebug einrichten, den Worker lokal deaktivieren und messenger:consume
manuell ausführen, da dies mehr Kontrolle beim Debuggen von Code bietet, der durch die Nachrichten ausgeführt wird.
Fast alles, was wir wissen müssen, findet sich in ElasticsearchProductDefinition.php
. Setzen Sie Breakpoints in allen drei öffentlichen Funktionen (getMapping
, buildTermQuery
und fetch
), um sich mit dem Prozess vertraut zu machen.
getMapping
definiert das Mapping, eine Blaupause dafür, wie ein Dokument indexiert und wie Felder gespeichert werden.fetch
ruft tatsächlich die Produkte ab und gibt Dokumente zurück.buildTermQuery
definiert die Abfrage, die verwendet wird, um Produkte basierend auf einem bestimmten Begriff in der Suchleiste zurückzugeben.
Mit gesetzten Breakpoints und dem laufenden messenger:consume
-Befehl öffnen Sie ein zusätzliches Terminal und führen Sie aus:
bin/console es:index
Es macht keinen Sinn, das Lesen, Debuggen und Erklären des Codes in einem Blog zu behandeln, daher hoffe ich, dass Sie sich etwas Zeit genommen haben, um zu debuggen und der Logik zu folgen, denn mit diesem Befehl ist viel passiert. Ihre Listenseiten zeigen nun Produkte an, und Ihre Suchleiste liefert Ergebnisse, weil wir jetzt Produktindizes haben.
Wenn Sie GET _cat/indices?v
erneut ausführen, sehen Sie einen neuen Eintrag: Produktindex. Wir haben jetzt einen Produktindex mit dem Präfix aus der .env
-Datei und einem Unix-Zeitstempel.
Sie können das Produkt-Mapping mit der folgenden Abfrage in Kibana überprüfen:
GET /blog_product/_mapping
Lassen Sie uns nun einen Blick auf ein Produkt werfen:
Ein bisschen off-topic, aber dieses Bild zeigt einen weiteren großen Vorteil der Verwendung von Kibana – wir können beliebig viele Abfragen vorbereiten und auswählen, welche ausgeführt werden sollen.
Beim Debuggen werden Sie möglicherweise bemerken, dass innerhalb der Funktion getMapping()
ein interessanter Abschnitt übersprungen wird, weil unsere APP_ENV
auf dev
gesetzt ist.
Wenn Sie zur prod
-Umgebung wechseln, sehen Sie nur id
und autoIncrement
. Beachten Sie, dass Sie, wenn Sie denselben Produktindex in der prod
-Umgebung wie zuvor angezeigt haben möchten, SHOPWARE_ES_EXCLUDE_SOURCE=1
in die .env
-Datei hinzufügen können. Lassen Sie uns jedoch mit den Standardwerten fortfahren, also werde ich APP_ENV
in der .env
-Datei auf prod
umschalten (mit dem Standardwert SHOPWARE_ES_EXCLUDE_SOURCE=0
). Führen Sie nun die folgenden Befehle aus, um die aktuellen Indizes zu entfernen und neue zu erstellen:
bin/console es:reset
bin/console es:index
Jetzt sieht es so aus:
Es mag kontraintuitiv erscheinen, da es so aussieht, als würde nur die id
-Suche funktionieren, aber die Suche funktioniert völlig normal, da alle Felder indexiert und durchsuchbar sind; sie befinden sich nur nicht im _source
, um Speicherplatz zu sparen. Welche Felder durchsuchbar sind und wie die Ranking-Bewertung erfolgt, kann in der Administration angepasst werden.
Das Ein- oder Ausschließen von Feldern aus _source
ist eine Funktion, die es ermöglicht, den Inhalt des _source
-Feldes nach der Indexierung des Dokuments, aber vor der Speicherung des _source
-Feldes zu kürzen. Sie können mehr über dieses Thema hier lesen.
In einer Produktionsumgebung würden Sie nur zwei weitere tägliche Cron-Jobs benötigen, um diese Befehle auszuführen:
bin/console es:index
bin/console es:index:cleanup -f
Fazit
Elasticsearch verbessert die Leistung erheblich, und wenn Sie mit Elasticsearch vertraut sind, kann es auf viele Arten angepasst werden, um die perfekte Suche für Ihren Shop zu erreichen. Die Suche sollte schneller funktionieren, wenn Felder im _source
enthalten sind, aber viele Produktfelder sind für die Suche irrelevant, sodass es von den persönlichen Vorlieben abhängt. Sie könnten ein Plugin mit einem Decorator erstellen, um Elasticsearch an Ihre Bedürfnisse anzupassen. Zum Beispiel können Sie das "include"-Array erweitern und nur relevante Produktfelder hinzufügen, was schnellere Ergebnisse liefern und dennoch den Speicherplatz niedrig halten könnte. Sie können Abfragen modifizieren und alles Mögliche tun, solange Sie wissen, was Sie tun. Es wäre eine Verschwendung, eine so leistungsstarke Suchmaschine wie Elasticsearch nicht zu nutzen, wenn Shopware sie bereits unterstützt.
Haben Sie Fragen oder Feedback zum Artikel oder möchten Sie mehr über uns erfahren? Ich freue mich darauf, von Ihnen per E-Mail oder LinkedIn zu hören!