2 Eine Suchanwendung entsteht
Nachdem die Einführung einen ersten Blick auf Elasticsearch ermöglicht hat, gehen wir in diesem Kapitel direkt zur Praxis über. Wir implementieren eine typische Suchanwendung von Grund auf und lernen dabei wichtige Eigenschaften von Elasticsearch, wie die Indizierung, unterschiedliche Abfragen und die Möglichkeit zur Facettierung kennen.
2.1 Die Beispielanwendung
Wir werden viele Eigenschaften von Elasticsearch an einem durchgehenden Beispiel ansehen, das uns in diesem und den nächsten Kapiteln begleiten wird: eine einfache Anwendung zur Suche nach Vortragsbeschreibungen. Wir können uns vorstellen, dass ein Konferenzveranstalter ein Archiv zur Verfügung stellen will, in dem Details zu den Inhalten der Vorträge und den Metadaten wie Sprecher oder Datum zur Verfügung stehen. Die Benutzer können damit für sie interessante Vorträge finden.
Abbildung 2-1: Screenshot einer klassischen Suchanwendung
In der Einführung haben wir bereits gesehen, wie einfach Elasticsearch installiert werden kann. Kapitel 10 bietet noch weitere Details dazu.
In einer ersten Iteration unserer Anwendung können wir uns eine einfache Suchseite mit Eingabefeld vorstellen, in das der Nutzer einzelne Schlüsselwörter eingeben kann. In einer Liste werden die zugehörigen Vorträge mit einigen ihrer Informationen angezeigt. Abbildung 2-1 zeigt, wie die Anwendung in einer ersten Iteration aussehen könnte.
2.1.1 Die Beispieldaten
Elasticsearch akzeptiert zu speichernde Daten in Form von JSON-Dokumenten. Woher diese Daten ursprünglich kommen, spielt zuerst einmal keine Rolle. Vorerst wird davon ausgegangen, dass die Vortragsdaten bereits im richtigen Format vorliegen. Ein erstes Beispiel kann folgendermaßen aussehen. Die Struktur wird im Laufe des Buches noch erweitert.
{
"title" : "Anwendungsfälle für Elasticsearch",
"speaker" : "Florian Hopf",
"date" : "2014-07-17T15:35:00.000Z",
"tags" : ["Java", "Lucene"],
"conference" : {
"name" : "Java Forum Stuttgart",
"city" : "Stuttgart"
}
}
Wir sehen, dass das Dokument unterschiedliche Eigenschaften hat. Manche davon sind Texte, wie title oder speaker. Das Datumsfeld date ist zwar ein JSON-String, ist allerdings in einem standardisierten Datumsformat hinterlegt. Die Schlagwörter zum Vortrag in dem Feld tags sind ein Array, die Konferenz, auf der der Vortrag stattfindet, ist schließlich noch als Subdokument hinterlegt.
Elasticsearch kann mit JSON dieser Art umgehen, das Dokument kann wie es ist gespeichert werden.
Was die Datenmenge angeht, werden wir uns in den ersten Kapiteln auf einige wenige Dokumente beschränken, da die Funktionalität im Vordergrund steht. Was zu beachten ist, wenn die Menge der Daten ansteigt, werden wir in späteren Kapiteln genauer betrachten.
2.2 Dokumente indizieren
Der erste Schritt zu einer Suchlösung besteht darin, unsere Dokumente in Elasticsearch zu speichern. Dazu ist es wichtig, die beiden Konzepte Index und Typ zu verstehen.
2.2.1 Index und Typ
Ein Index in Elasticsearch bildet eine logische Einheit zur Sammlung von Dokumenten. Welche Dokumente das sind, wird von der Anwendung bestimmt. In unserem Fall verwendet die Beispielapplikation nur den Index conference zur Speicherung aller Dokumente zu einer Konferenz. Wenn wir das Konzept mit der relationalen Welt vergleichen, entspricht ein Index einer Datenbank, die ebenfalls eine logische Sammlung von Entitäten ist. In einigen Bereichen weicht Elasticsearch hier jedoch deutlich ab, beispielsweise kann man mehrere Indizes gleichzeitig abfragen, was bei relationalen Datenbanken normalerweise nicht möglich ist.
Der Typ eines Dokuments beschreibt die Struktur der indizierten Dokumente. Für jede eigenständige Einheit, die wir im Index speichern wollen, existiert ein Typ. Für unsere Anwendung starten wir mit dem Typ talk, der Informationen zu den Vorträgen enthält. Ein weiterer möglicher Typ könnte speaker für Informationen zur Sprecherin sein. Wenn wir unseren Vergleich mit der relationalen Welt fortführen, sind die Typen vergleichbar mit Tabellen, allerdings gibt es auch hier im Detail starke Abweichungen.
Abbildung 2-2 visualisiert die Beziehung zwischen Index und Typ in einem Elasticsearch-Cluster mit dem Index conference zur Speicherung der Konferenzdaten und dem beispielhaften Index interaction zur Speicherung der Kommentare und Benutzerwertungen, die auf einer Homepage abgegeben werden können.
Abbildung 2-2: Mehrere Indizes und Typen in einer Elasticsearch-Instanz
Wie in Kapitel 1 erwähnt, erfolgt der Zugriff auf Elasticsearch meist über HTTP. Die URL enthält dann Informationen zum zu verwendenden Index im ersten Pfadsegment und zum Typ im zweiten Segment. Die gesamte URL entspricht dem Schema http://{host}:{port}/{index}/{typ}, also beispielsweise http://localhost:9200/conference/talk/.
Zugriff auf Elasticsearch
Auch wenn der Zugriff über HTTP es nahelegt: Elasticsearch sollte nur in Ausnahmefällen direkt im Internet verfügbar sein. In Kapitel 9 und 10 werden einige Aspekte zur Produktivnahme von Elasticsearch beschrieben.
2.2.2 Indizierung
Wie wir schon in der Einführung gesehen haben, können wir neue Dokumente einfach per HTTP-POST-Request hinzufügen. Index und Typ werden automatisch angelegt, wenn sie noch nicht existieren. Wird eine eigene ID vergeben, beispielsweise eine bestehende Datenbank-ID, können wir ein neues Dokument auch über einen PUT-Request anlegen und die ID mit in der URL übergeben.
curl -XPUT "http://localhost:9200/conference/talk/1" -d'
{
"title" : "Anwendungsfälle für Elasticsearch",
"speaker" : "Florian Hopf",
"date" : "2014-07-17T15:35:00.000Z",
"tags" : ["Java", "Lucene"],
"conference" : {
"name" : "Java Forum Stuttgart",
"city" : "Stuttgart"
}
}'
Wird keine ID angegeben, kann Elasticsearch diese generieren. Der vergebene Wert ist in der Antwort des Indizierungsaufrufs enthalten. Anhand der ID kann per GET-Request auf das Dokument zugegriffen werden.
curl -XGET "http://localhost:9200/conference/talk/1"
Für viele Anwendungen, in denen Elasticsearch nur zur Suche eingesetzt wird, ist der Zugriff anhand der ID eher selten. Wir können dadurch jedoch direkt sehen, dass unser Dokument vorhanden ist.
2.2.3 Die erste Suche
Wie mittlerweile üblich, soll unseren Benutzern der Zugriff auf die indizierten Vorträge per Suche nach Schlüsselwort möglich sein – die Stärke von Elasticsearch. Eine Nutzerin kann einen oder mehrere Begriffe in das Eingabefeld eingeben und wenn der Begriff im Dokument vorkommt, soll der Vortrag als Treffer in der Liste auftauchen.
Elasticsearch stellt unterschiedliche Suchmöglichkeiten zur Verfügung. Im einfachsten Fall wird ein GET-Request auf den _search-Endpunkt ausgeführt. Der Parameter q wird verwendet, um den Suchbegriff des Nutzers zu übergeben. Die folgende Abfrage fordert alle Dokumente an, die den Begriff Elasticsearch enthalten.
curl -XGET "http://localhost:9200/conference/talk/_search?q=Elasticsearch"
Elasticsearch schickt uns auf diese Anfrage eine ausführliche Antwort, die auch unser ursprünglich indiziertes Dokument enthält.
{
"took": 35,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.067124054,
"hits": [
{
"_index": "conference",
"_type": "talk",
"_id": "1",
"_score": 0.067124054,
"_source": {
"title": "Anwendungsfälle für Elasticsearch",
"speaker": "Florian Hopf",
"date":...