Elasticsearch ermöglicht es, ohne großen Aufwand eine Systemlandschaft um eine performante Suche auf große Datenmengen zu erweitern. Weil Elasticsearch die Daten im JSON-Format speichert, fällt es in die Kategorie der NoSQL-Datenbank. Die Grundlagen der Terminologie und das Aufsetzen dieser Open-Source-Software befinden sich in Teil 1 dieses Artikels. Außerdem werden dort die Erstellung sowie Konfiguration eines Index und dessen Mappings behandelt.

Die Suchmaschine bietet eine REST-API für das Schreiben und Suchen an, welche in diesem Teil genauer beleuchtet wird. Zusätzlich werden einige Funktionen besprochen, die es erlauben, Suchende leichter zum Ziel zu führen. Unabhängig davon, ob die Suche in einer Web-Oberfläche oder rein technisch zur Datenanalyse verwendet wird, ist es wichtig zu verstehen, wie sich die getroffenen Ergebnisse zusammensetzen.

Dieser Artikel gibt verschiedene Methoden an die Hand, um nachzuvollziehen, wieso welches Ergebnis an welcher Position gefunden wird, obwohl es vielleicht überhaupt nicht erwartet wurde. Die erstellten Code-Segmente sind für die Kibana Dev Tools optimiert. Eine kurze Einleitung zur Ausführung befindet sich ebenfalls im ersten Teil.

Erstes Dokument schreiben

Dokumente können einzeln oder gebündelt als Bulk eingefügt werden. Wenn dynamisches Mapping aktiviert ist, werden unbekannte Felder automatisch im Mapping ergänzt.

Ein einzelnes Dokument kann mit einem Insert Request angelegt werden:

Wenn der Datensatz erzeugt wurde, kann aus der Response die generierte ID und weitere Informationen zu Shards entnommen werden.

Dokument löschen

Zum Löschen von einzelnen Einträgen kann der Delete Request auf die _doc-Schnittstelle ausgeführt werden. Dafür muss die ID des Dokuments verwendet werden. Diese steht in der Antwort nach der Erstellung, kann aber nachträglich auch mithilfe einer Suchabfrage oder über die Kibana-Oberfläche abgerufen werden.

Mehrere Dokumente schreiben

Wenn mehrere Daten gleichzeitig eingefügt werden sollen, zum Beispiel zur initialen Befüllung, kann ein Bulk-Aufruf verwendet werden.

Häufige Fehler sind, dass die Daten nicht in einer Zeile formatiert sind. Wenn sich in den Datensätzen Zeilenumbrüche oder zwischen den Aufzählungen Kommata befinden, wird der Request nicht verarbeitet und folgende Fehlermeldung zurückgegeben:

Hier ein direkter Vergleich zwischen der richtigen und der falschen Formatierung für diesen Aufruf:

Ein weiterer häufiger Fehler, wenn der Request nicht mit Kibana versendet wurde, ist eine fehlende leere Zeile am Ende:

Beim Ausführen des Bulk-Requests sollte aufgepasst werden, dass keine automatische Code-Formatierung des JSONs stattfindet. Wird zum Beispiel die Formatierung von der Postman Beautify-Funktion genutzt, entstehen sowohl die Fehler für die Zeilenumbrüche als auch der Leerzeile.

Wenn die Formatierung und Daten gültig sind, enthält die Success-Response alle angelegten Dokumente. Sollte ein Teil der Dokumente fehlerhaft sein, werden die gültigen Einträge trotzdem verarbeitet und eingefügt.

Index und Daten in Kibana ansehen

Nachdem die ersten Dokumente erstellt wurden, können sie in Kibana im Search-Bereich unter Indices/PERSON/Documents eingesehen werden.

Wenn lokal gearbeitet wird, befindet sich der Reiter unter dieser URL:

http://localhost:5601/app/enterprise_search/content/search_indices/person/documents

Wenn der Index anders benannt wurde, muss die Stelle „Person“ aus der URL entsprechend ausgetauscht werden.

Performante Suche Abbildung 1 - Index und Daten in Kibana ansehen

In dieser Ansicht kann ebenfalls die ID der Dokumente abgerufen werden. Sie versteckt sich unter dem Info-Button:

Performante Suche Abbildung 2 - Document metadata ID

Match All

Mit dieser Abfrage können alle Einträge eines Index abgerufen werden. Wenn die Standardkonfiguration verwendet wird, kann diese Schnittstelle maximal 10.000 Einträge ausgeben.

Als Antwort erhalten wir alle bisher erstellten Personen.

Match

Wenn nur ein bestimmter Teil der Daten abgefragt werden soll, kann die Match-Abfrage verwendet werden. Die verschiedenen Feldtypen können auf unterschiedliche Arten durchsucht werden.

Bei dieser Abfrage wird das “Name”-Textfeld durchsucht.

Wenn mit dieser Abfrage eine einzelne Person gefunden werden sollte, ist es sicher überraschend, zwei Treffer als Antwort zu erhalten.

In dem bestehenden Beispiel werden zum einen “Mickey Mouse”, aber auch “Minnie Mouse” aufgelistet.

Tokenisierung

Ein Token ist Teil eines Volltexts. Der Suchtext sowie der gespeicherte Text werden durch den Elasticsearch Standard-Tokenizer modifiziert. Dieser spaltet den Text in einzelne Token an Wortgrenzen wie Leerzeichen oder Bindestrichen. Außerdem werden die Satzzeichen entfernt und der Text in Kleinbuchstaben transformiert. In dem vorherigen Beispiel wird der Namen aufgeteilt und der angegebene Vor- und Nachnamen einzeln durchsucht.

Das führt dazu, dass bei dem Nachnamen zwei Einträge gefunden werden, obwohl der Text als Ganzes einen Treffer erzielen würde.

Ein wichtiges Merkmal an den Ergebnissen ist der Score.

Hier ist ersichtlich, dass ein Treffer auf mehrere der Teilwörter höher gewichtet wird, als ein Treffer auf ein einzelnes.

Trefferanalyse

Wenn zu irgendeinem Zeitpunkt unklar ist, wieso welche Ergebnisse getroffen werden und wie sich der Score zusammensetzt, kann mit dem Attribut “explain” gearbeitet werden:

Die Antwort enthält nun für jeden Eintrag eine Zusammensetzung des Scorings. Diese enthält die jeweiligen Token und spezifische Berechnungsdetails. In diesem Fall enthält die Erklärung für den Top-Treffer einen Abschnitt für das Token des Vornamens und des Nachnamens, während der zweite Treffer nur den Score für den Nachnamen erhält.

Wenn das exakte Scoring und die mathematischen Details nicht relevant für die Analyse sind, kann der Suchbegriff analysiert werden.

Hier wird sehr gut deutlich, welche Werte letzten Endes für die Suche verwendet werden. Außerdem wird die Funktionalität des Standard-Tokenizer veranschaulicht.

Diese beiden Optionen werden besonders dann spannend, wenn nicht mehr mit den Standardeinstellungen für die Text-Modifikation gearbeitet wird.

Delete by Query

Wenn mehrere Einträge gelöscht werden sollen, kann eine Löschabfrage definiert werden. Die eben definierte Abfrage kann nun genutzt werden, um alle gelieferten Ergebnisse zu löschen. Dafür muss diese nur gegen _delete_by_query ausgeführt werden.

Vor dem Ausführen sollte sichergestellt werden, dass eindeutig klar ist, welche Einträge getroffen werden. Es empfiehlt sich bei undurchsichtigen Suchkriterien wie zum Beispiel Text, die Abfrage erst als Suchabfrage auszuführen, bevor sie zum Löschen verwendet wird.

Normalizer

Mithilfe von Normalizern kann der zu speichernde Text oder der Suchtext weiter modifiziert werden. Es gibt vordefinierte Normalizer, die zum Beispiel Sprach-Normalisierungen beinhalten.

Die Normalisierung kann ebenfalls durch den _analyze-Endpunkt ausgelöst werden.

Der englische Normalizer transformiert zu Kleinbuchstaben und verwandelt konjugierte Verben zurück in den Infinitiv.

Baking → bake

Der Plural wird zum Singular:

Breads → bread

Das y am Ende wird zu einem i:

Mickey → mickei

Das Endergebnis der Normalisierung ist wie folgt:

Wird der Suchtext ebenfalls normalisiert, scheitert zum Beispiel die Suche nach einem Zitat nun nicht mehr an der Vergangenheitsform oder einem falschen Plural.

des Feld nachträglich mit einer Normalisierung aufzurüsten. Wenn der bestehende Index bereits das E-Mail-Feld enthält, müsste dieser gelöscht und mit der Erweiterung neu aufgesetzt werden.

Wenn nun ein Dokument geschrieben wird, dass Großbuchstaben in der normalisierten E-Mail hat, wird diese vor dem Schreiben transformiert.

Term Queries

Mit einer Term-Query können Suchen ausgeführt werden, bei denen das Suchkriterium und der gespeicherte Wert exakt übereinstimmen. Elasticsearch empfiehlt, diese nicht für Textfelder zu suchen, da diese vor dem Speichern modifiziert werden, sodass es schwierig ist nach dem exakten, transformierten Text zu suchen.

Bei der Suche auf dem Keyword-Feld mit dem Lowercase-Normalizer, wird dieser ebenfalls auf die Suche ausgeführt. In diesem Beispiel verwenden wir eine Term-Query, um auf dem E-Mail-Feld zu suchen.

Term-Vector

Eine weitere Methode zur Analyse der gespeicherten Inhalte ist die _termvectors-Schnittstelle. Diese bekommt die ID eines bestimmten Dokumentes und kann weitere Spezifikationen zu Statistiken und Häufigkeit des Begriffes in einem Text enthalten. Außerdem kann die Position des Begriffs mit Start und Ende der Zeichen eingesehen werden.

Um die Antwort übersichtlich zu halten, sind diese Spezifikationen in der Suchabfrage ausgeschaltet.

Als Antwort erhalten wir die drei Bestandteile des Namens, wie sie nach der Anwendung des Standard-Tokenizers gespeichert wurden. Außerdem wird die Häufigkeit des Begriffs ausgegeben. Für einen Namen ist diese Information nicht sonderlich spannend, aber für Suchanfragen auf Fließtexte durchaus relevant.

Sorting

Eine Suche kann sehr einfach um ein oder mehrere Sortierungskriterien ergänzt werden. Die Suchkriterien werden der Reihe nach angewendet. Wenn zwei Ergebnisse dieselben Werte für das Sortierkriterium haben, zum Beispiel das Alter, dann wird – sofern vorhanden – das zweite Kriterium genutzt.

Performante Suche mit Elasticsearch – Fazit

Mit Elasticsearch können Dokumente schnell und einfach in lesbarem JSON-Format über die REST-API indiziert werden. Mit den verschiedenen Suchanfragen können sie mühelos gefunden werden. Es ist jedoch wichtig zu verstehen, wie sich die Felddefinition auf die jeweilige Suche auswirkt.

Sind in einem Textfeld mehrere Worte enthalten, werden sie standardmäßig in einzelne Token aufgespalten – sowohl im indizierten Dokument als auch im Suchtext. So kann ein Treffer für einen Teil des Textes gefunden werden, wie zum Beispiel der gleiche Nachname. Texte können zudem durch bestehende Elasticsearch-Funktionen, wie zum Beispiel der Sprachnormalisierung, sehr einfach noch besser durchsuchbar gemacht werden, und mit der Sortierungsfunktion kann die Suche und deren Ergebnisse noch weiter optimiert werden.

Elasticsearch bietet sehr viele Optionen, um das Durchsuchen von insbesondere Texten möglichst einfach umzusetzen. Hierbei gibt es viele Möglichkeiten, um mögliche Formulierungen und Schreibweisen zum richtigen Ergebnis zu verhelfen. Die verschiedenen Analyse-Methoden helfen, bei diesen komplexen Suchen oder Transformierungen die Schritte und Ergebnisse nachzuvollziehen.

Mit diesen ersten Schritten besteht eine gute Grundlage, um die erste Suche zum gewünschten Zielbild weiter zu verfeinern. Für die weiteren Verfeinerungen ist die Elasticsearch-Dokumentation sehr zu empfehlen. Sie ist detailliert, lesbar und enthält viele Beispiele für alle erdenklichen Anwendungsszenarien.

Bis dahin, happy elastic searching!

Lisa Messerli

Große Auswahl an günstigen Domain-Endungen – schon ab 0,08 € /Monat
Jetzt Domain-Check starten