Engineering

Praktische Einführung in Elasticsearch

Anmerkung des Autors (3. August 2021): Dieser Beitrag verwendet veraltete Features. In der Dokumentation zum Thema Map custom regions with reverse geocoding (benutzerdefinierte Regionen mit umgekehrter Geocodierung zuordnen) finden Sie eine aktuelle Anleitung.

Welchen Zweck hat dieser Beitrag?

Kürzlich hatte ich das Vergnügen, eine Master-Class zum Thema „Informationsabruf und semantisches Web“ an der Universität von A Coruña unterrichten zu dürfen. Dabei ging es hauptsächlich darum, einen grundlegenden Überblick über Elasticsearch zu vermitteln, damit sie Elasticsearch in ihren Kursaufgaben einsetzen können. Einige Teilnehmer waren bereits mit Lucene vertraut, aber ein Teil des Kurses hatte sich noch nie mit dem Thema Informationsabruf beschäftigt. Da der Kurs erst um 19:30 Uhr begann, musste ich mir etwas einfallen lassen, um die Aufmerksamkeit der Teilnehmer zu fesseln (und sie davon abzuhalten, einzuschlafen!). Was die Aufmerksamkeit angeht, gibt es zwei praktische Ansätze: Schokolade mitbringen – was ich leider vergessen habe – oder eine möglichst praxisorientierte Vorlesung halten.

Darum geht es auch in diesem Blogeintrag: Wir werden uns den praktischen Teil dieser Vorlesung ansehen. Es geht nicht darum, sämtliche Befehle oder Anfragen in Elasticsearch zu kennen (dafür gibt es die Dokumentation), sondern Ihnen zu zeigen, wie Sie ohne Vorkenntnisse in einem 30-60-minütigen Tutorial mit Elasticsearch experimentieren und Spaß haben können. Kopieren Sie die einzelnen Anfragen und fügen Sie sie ein, um die Ergebnisse zu sehen, und versuchen Sie, die Fragestellungen zu lösen.

An wen richtet sich dieser Blogeintrag?

Ich werde die wichtigsten Elastic-Features anhand von einigen Grundkonzepten vorstellen, gelegentlich etwas technischere und komplexe Konzepte ansprechen und die Dokumentation zur weiteren Referenz verlinken (nicht vergessen: zur weiteren Referenz. Sie können jederzeit mit den Beispielen fortfahren und sich die Dokumentation für später aufheben.). Falls Sie Elasticsearch noch nie verwendet haben, aber gerne in Aktion erleben – und dabei die Zügel in der Hand behalten – möchten, dann ist dieser Blogeintrag für Sie gedacht. Falls Sie sich mit Elasticsearch auskennen, sehen Sie sich den Datensatz an, den wir verwenden werden: Wenn Sie nach dem Nutzen von Elasticsearch gefragt werden, können Sie die Suche in Shakespeare-Stücken als Beispiel anführen!

Was werden wir (nicht) behandeln?

Zunächst werden wir einige Dokumente hinzufügen, nach ihnen suchen und sie anschließend wieder entfernen. Anschließend verwenden wir einen Shakespeare-Datensatz, um uns näher mit Suchfunktionen und Aggregationen zu befassen. Sie erfahren, wie Sie Elasticsearch sofort und praxisorientiert einsetzen können.

Wir befassen uns nicht mit der Konfiguration oder mit Best Practices für Produktions-Deployments, sondern vermitteln Ihnen lediglich einen Überblick über die Möglichkeiten von Elasticsearch, damit Sie selbst beurteilen können, ob sich die Lösung für Ihre Anforderungen eignet.

Einrichtung

Zuallererst brauchen Sie Elasticsearch. In der Installationsanleitung, Dokumentation nur auf Englisch verfügbar erfahren Sie, wie Sie die aktuelle Version herunterladen, installieren und starten können. Dazu benötigen Sie eine aktuelle Version von Java, müssen Elasticsearch für Ihr Betriebssystem herunterladen und installieren und anschließend unter „bin/elasticsearch“ mit den Standardwerten ausführen. Für diese Lektion verwenden wir die neueste verfügbare Version: 5.5.0.

Anschließend können Sie mit Elasticsearch kommunizieren: dazu senden Sie HTTP-Anforderungen an die REST-API. Elastic wird standardmäßig unter Port 9200 ausgeführt. Für den Zugriff können Sie ein Tool verwenden, mit dem Sie sich bereits auskennen (wie etwa curl für Linux), REST-Browser-Plugins für Chrome oder Firefox, oder Sie können einfach Kibana installieren und das Konsolen-Plugin verwenden. Jede Anforderung besteht aus einem HTTP-Verb (GET, POST, PUT usw.), einem URL-Endpunkt und einem optionalen Text (in den meisten Fällen ein JSON-Objekt).

Um sich zu vergewissern, dass Elasticsearch ausgeführt wird, können Sie beispielsweise eine GET-Anforderung ohne jeglichen Text an die Basis-URL (also den Standard-Endpunkt) senden:

GET localhost:9200

Die Antwort sollte in etwa wie folgt aussehen. Da wir die Konfiguration nicht angefasst haben, ist der Name unserer Instanz eine zufällige, 7-stellige Zeichenfolge:

{
    "name": "t9mGYu5",
    "cluster_name": "elasticsearch",
    "cluster_uuid": "xq-6d4QpSDa-kiNE4Ph-Cg",
    "version": {
        "number": "5.5.0",
        "build_hash": "260387d",
        "build_date": "2017-06-30T23:16:05.735Z",
        "build_snapshot": false,
        "lucene_version": "6.6.0"
    },
    "tagline": "You Know, for Search"
}

Einige einfache Beispiele

Wir haben bereits eine frische Elasticsearch-Instanz initialisiert und ausgeführt. Als nächstes werden wir einige Dokumente hinzufügen und abfragen. Dokumente in Elasticsearch werden im JSON-Format abgebildet. Außerdem werden Dokumente zu Indizes hinzugefügt und haben einen bestimmten Typ. Wir fügen ein Dokument mit dem Typ „person“ und der ID 1 zum Index mit dem Namen „accounts“ hinzu. Der Index existiert noch nicht und wird daher von Elasticsearch automatisch erstellt.

POST localhost:9200/accounts/person/1 
{
    "name" : "John",
    "lastname" : "Doe",
    "job_description" : "Systemadministrator und Linux-Expete"
}

Die Antwort enthält Informationen über die Dokumenterstellung:

{
    "_index": "accounts",
    "_type": "person",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "created": true
}

Nachdem das Dokument erstellt wurde, können wir es abrufen:

GET localhost:9200/accounts/person/1 

Das Ergebnis enthält Metadaten sowie das komplette Dokument (im Feld „_source“):

{
    "_index": "accounts",
    "_type": "person",
    "_id": "1",
    "_version": 1,
    "found": true,
    "_source": {
        "name": "John",
        "lastname": "Doe",
        "job_description": "Systemadministrator und Linux-Expete"
    }
}

Aufmerksamen Lesern ist bestimmt schon der Schreibfehler in der Jobbeschreibung (Expete) aufgefallen. Wir können diesen Fehler mit einem Update-Befehl („_update“) korrigieren:

POST localhost:9200/accounts/person/1/_update
{
      "doc":{
          "job_description" : "Systemadministrator und Linux-Experte"
       }
}

Die Operation wird ausgeführt und das Dokument wird geändert. Jetzt können wir es erneut abrufen und uns die Antwort ansehen:

{
    "_index": "accounts",
    "_type": "person",
    "_id": "1",
    "_version": 2,
    "found": true,
    "_source": {
        "name": "John",
        "lastname": "Doe",
        "job_description": "Systemadministrator und Linux-Experte"
    }
}

Für die nächsten Operationen fügen wir ein weiteres Dokument mit der ID 2 hinzu:

POST localhost:9200/accounts/person/2
{
    "name" : "John",
    "lastname" : "Smith",
    "job_description" : "Systemadministrator"
}

Bisher haben wir Dokumente anhand ihrer ID abgerufen, aber noch keine Suche ausgeführt. In unseren Anforderungen an die Rest-API können wir die Abfrage im Text der Anforderung oder mit einer bestimmten Syntax auch direkt in der URL angeben. In diesem Abschnitt führen wir Suchvorgänge direkt in der URL im Format „/_search?q=irgendetwas“ aus:

GET localhost:9200/_search?q=john

Diese Suche liefert beide Dokumente zurück, da beide den Namen john enthalten:

{
    "took": 58,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 2,
        "max_score": 0.2876821,
        "hits": [
            {
                "_index": "accounts",
                "_type": "person",
                "_id": "2",
                "_score": 0.2876821,
                "_source": {
                    "name": "John",
                    "lastname": "Smith",
                    "job_description": "Systemadministrator"
                }
            },
            {
                "_index": "accounts",
                "_type": "person",
                "_id": "1",
                "_score": 0.28582606,
                "_source": {
                    "name": "John",
                    "lastname": "Doe",
                    "job_description": "Systemadministrator und Linux-Experte"
                }
            }
        ]
    }
}

In diesem Ergebnisse sehen wir die übereinstimmenden Dokumente zusammen mit einigen Metadaten wie etwa der Gesamtzahl der Ergebnisse für unsere Anfrage. Suchen wir noch etwas weiter. Überlegen Sie sich, welche Dokumente zurückgegeben werden, bevor Sie die Suchabfragen ausführen (die Antwort folgt jeweils auf den Befehl):

GET localhost:9200/_search?q=smith

Diese Suche liefert nur das zuletzt hinzugefügte Dokument zurück, da es den Namen smith enthält.

GET localhost:9200/_search?q=job_description:john

Diese Suche gibt kein Dokument zurück. In diesem Fall schränken wir unsere Suche auf das Feld „job_description“ ein, das den Begriff nicht enthält. Überlegen Sie sich als Übung Folgendes: – eine Suche in diesem Feld, die nur das Dokument mit der ID 1 zurückgibt – eine Suche in diesem Feld, die beide Dokumente zurückgibt – eine Suche in diesem Feld, die nur das Dokument mit der ID 2 zurückgibt (dazu ein Tipp: der Parameter „q“ verwendet dieselbe Syntax wie die Abfragezeichenfolge

Aus dem letzten Beispiel ergibt sich eine Frage: Wenn wir bestimmte Felder durchsuchen können, können wir dann auch in einem bestimmten Index suchen? Die Antwort ist ja: Wir können Index und Typ in der URL angeben. Probieren Sie Folgendes aus:

GET localhost:9200/accounts/person/_search?q=job_description:linux

Wir können nicht nur in einem bestimmten Index suchen, sondern auch mehrere Indizes gleichzeitig mit einer kommagetrennten Listen an Indexnamen angeben. Dasselbe gilt für Typen. Weitere Informationen zu den zusätzlichen verfügbaren Optionen finden Sie unter Multi-Index, Multi-type. Zur weiteren Übung können Sie versuchen, Dokumente zu einem zweiten (separaten) Index hinzuzufügen und beide Indizes gleichzeitig zu durchsuchen.

Bevor wir diesen Abschnitt beenden, werden wir noch ein Dokument und anschließend den gesamten Index löschen. Löschen Sie das Dokument und versuchen Sie anschließend, es abzurufen oder mit einer Suche zu finden.

DELETE localhost:9200/accounts/person/1

Die Antwort enthält eine Bestätigung:

{
    "found": true,
    "_index": "accounts",
    "_type": "person",
    "_id": "1",
    "_version": 3,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    }
}

Zuletzt können wir den gesamten Index löschen.

DELETE localhost:9200/accounts

Damit haben wir das Ende des ersten Abschnitts erreicht. Bisher haben wir:

  1. ein Dokument hinzugefügt. Dabei wurde implizit ein Index erstellt (der zuvor nicht existierte).
  2. das Dokument abgerufen.
  3. das Dokument aktualisiert, um einen Tippfehler zu korrigieren, und die Korrektur überprüft.
  4. ein zweites Dokument hinzugefügt.
  5. unter anderem implizit sämtliche Felder sowie nur ein einzelnes Feld durchsucht.
  6. verschiedene Suchübungen vorgeschlagen.
  7. uns angesehen, wie wir verschiedene Indizes und Typen gleichzeitig durchsuchen können.
  8. mehrere Indizes gleichzeitig durchsucht.
  9. ein Dokument gelöscht.
  10. einen gesamten Index gelöscht.

Weitere Informationen zu den Themen in diesem Abschnitt finden Sie unter den folgenden Links:

Index-APIGet-APIDelete-APIUpdate-APIURI-Suche

Lassen Sie uns mit etwas interessanteren Daten spielen.

Bisher haben wir fiktive Daten verwendet. In diesem Abschnitt werden wir uns mit Shakespeare-Stücken befassen. Laden Sie daher zunächst die Datei „shakespeare.json“ unter Kibana: Beispieldaten laden herunter. Mit der Bulk-API von Elasticsearch können Sie die Operationen zum Hinzufügen, Löschen, Aktualisieren und Erstellen massenhaft („bulk“) ausführen. Die Daten in dieser Datei können mit dieser API ingestiert und in einem Index mit dem Namen „Shakespeare“ indexiert werden und enthalten Dokumente mit den Typen „act“ (Akt), „scene“ (Szene) und „line“ (Zeile). Der Anfragetext an die Bulk-API enthält ein JSON-Objekt pro Zeile. Beim Hinzufügen, wie etwa in dieser Datei, finden Sie dort das JSON-Objekt Metadaten zur Operation sowie ein zweites JSON-Objekt in der nächsten Zeile mit dem hinzuzufügenden Dokument:

{"index":{"_index":"shakespeare","_type":"act","_id":0}}
{"line_id":1,"play_name":"Henry IV","speech_number":"","line_number":"","speaker":"","text_entry":"ACT I"}

Wir werden uns nicht näher mit der Bulk-API befassen. Falls Sie mehr darüber erfahren möchten, empfehlen wir Ihnen die Bulk-Dokumentation.

Importieren wir nun die Daten nach Elasticsearch. Der Text dieser Anforderung ist ziemlich groß (mehr als 200.000 Zeilen). Daher empfiehlt sich die Verwendung eines Tools, das den Anforderungstext aus einer Datei laden kann, wie etwa curl:

curl -XPOST "localhost:9200/shakespeare/_bulk?pretty" --data-binary @shakespeare.json

Nachdem die Daten geladen wurden, können wir sie durchsuchen. Im vorherigen Abschnitt haben wir unsere Suchabfragen in der URL übergeben. In diesem Abschnitt stellen wir die Abfrage-DSL vor, mit der wir unsere Abfragen als JSON im Text von Suchanforderungen definieren können. Je nach Operationstyp können Abfragen mit den Verben GET und POST gestellt werden. Beginnen wir mit der einfachsten Anfrage, indem wir alle Dokumente abrufen. Dazu geben wir im Text den Schlüssel „query“ mit dem Wert „match_all“ an.

GET localhost:9200/shakespeare/_search
{
    "query": {
            "match_all": {}
    }
}

Das Ergebnis enthält zehn Dokumente. Hier sehen Sie einen Teil der Ausgabe:

{
    "took": 7,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 111393,
        "max_score": 1,
        "hits": [
              ...          
            {
                "_index": "shakespeare",
                "_type": "line",
                "_id": "19",
                "_score": 1,
                "_source": {
                    "line_id": 20,
                    "play_name": "Henry IV",
                    "speech_number": 1,
                    "line_number": "1.1.17",
                    "speaker": "KING HENRY IV",
                    "text_entry": "The edge of war, like an ill-sheathed knife,"
                }
            },
            ...          

Das Suchformat ist ziemlich unkompliziert. Sie haben viele verschiedene Suchtypen zur Auswahl: Elastic unterstützt direkte Suchformen („Suche nach Begriff x“, „Suche Elemente im Bereich y“ usw.) sowie Verbundabfragen („a UND b“, „a ODER b“ usw.). Eine vollständige Referenz finden Sie in der Abfrage-DSL-Dokumentation. Wir werden uns hier lediglich einige Beispiele ansehen, um uns damit vertraut zu machen.

POST localhost:9200/shakespeare/scene/_search/
{
    "query":{
        "match" : {
            "play_name" : "Antony"
        }
    }
}

In dieser Abfrage suchen wir nach allen Szenen (siehe URL), in denen der Name des Stücks die Zeichenfolge Antony enthält. Wir können diese Suche verfeinern und nur die Szenen auswählen, in denen der Sprecher gleich Demetrius ist:

POST localhost:9200/shakespeare/scene/_search/
{
    "query":{
        "bool": {
            "must" : [
                {
                    "match" : {
                        "play_name" : "Antony"
                    }
                },
                {
                    "match" : {
                        "speaker" : "Demetrius"
                    }
                }
            ]
        }
    }
}

Ändern Sie diese Abfrage als erste Übung so ab, dass die Suche nicht nur Szenen mit dem Sprecher Demetrius zurückgibt, sondern auch Szenen mit dem Sprecher Antony (Tipp: sehen Sie sich die boolsche Klausel „should“ an). Als zweite Übung können Sie sich die verschiedenen Optionen für den Anforderungstext bei der Suche ansehen, etwa um auszuwählen, ab welcher Position in den Ergebnissen wir anfangen sollen und wie viele Ergebnisse wir erhalten möchten, um Paginierung zu unterstützten.

Bisher haben wir die Abfrage-DSL für unsere Abfragen verwendet. Wir könnten jedoch neben dem Abrufen gesuchter Dokumente auch einige Analysen durchführen. Dazu verwenden wir Aggregationen. Aggregationen liefern uns umfangreichere Einblicke in die Daten, zum Beispiel wie viele Stücke unser aktueller Datensatz enthält. Wie viele Szenen enthalten die Stücke durchschnittlich? Welche Stücke haben am meisten Szenen?

Bevor wir zu den praktischen Beispielen kommen, sehen wir uns jedoch die Erstellung unseres Shakespeare-Index genauer an, da etwas Theorie an dieser Stelle sehr hilfreich ist. In Elastic können wir Indizes erstellen, die festlegen, welche Datentypen die verschiedenen enthaltenen Felder haben können: numerische Felder, Schlüsselwortfelder, Textfelder usw. Wir haben jede Menge Datentypen zur Auswahl. Die Datentypen, die ein Index enthalten kann, werden mit Mappings definiert. In diesem Fall haben wir vor dem Indexieren der Dokumente keinen Index erstellt, darum hat Elastic die Typen der einzelnen Felder festgelegt und damit das Mapping für den Index erstellt. Für die Textfelder wurde der Typ „text“ ausgewählt. Dieser Typ ist analysiert, daher haben den „play_name“ Antony and Cleopatra mit der Suche nach Antony gefunden. Analysierte Felder unterstützen standardmäßig keine Aggregationen. Wie sollen wir also Aggregationen anzeigen, wenn die Felder diese nicht unterstützen? Elastic hat nicht nur die Typen der einzelnen Felder festgelegt, sondern auch eine nicht analysierte Version der Textfelder (namens „keyword“) angelegt, für den Fall, dass wir diese Felder aggregieren, sortieren oder in Skripts verwenden möchten: In unseren Aggregationen können wir einfach „play_name.keyword“ verwenden. Sehen Sie sich als zusätzliche Übung an, wie Sie die aktuellen Mappings untersuchen können.

Nach dieser kleinen und eher theoretischen Lektion kehren wir zurück an die Tastatur und wenden uns den Aggregationen zu! Wir untersuchen unsere Daten zunächst, indem wir die Anzahl der Theaterstücke abrufen:

GET localhost:9200/shakespeare/_search
{
    "size":0,
    "aggs" : {
        "Total plays" : {
            "cardinality" : {
                "field" : "play_name.keyword"
            }
        }
    }
}

Da wir uns nicht für die einzelnen Dokumente interessieren, haben wir angegeben, dass 0 Ergebnisse angezeigt werden sollen. Außerdem möchten wir den gesamten Index abfragen und haben daher keinen Abfragebereich angegeben: Die Aggregationen werden über alle Dokumente berechnet, die mit der Abfrage übereinstimmen, in diesem Fall mit dem Standardwert „match_all“. Zuletzt verwenden wir die Aggregation „cardinality“, die uns mitteilt, wie viele einzigartige Werte das Feld „play_name“ enthält.

{
    "took": 67,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 111393,
        "max_score": 0,
        "hits": []
    },
    "aggregations": {
        "Total plays": {
            "value": 36
        }
    }
}

Listen wir nun die Stücke auf, die in unserem Datensatz am häufigsten vorkommen:

GET localhost:9200/shakespeare/_search
{
    "size":0,
    "aggs" : {
        "Popular plays" : {
            "terms" : {
                "field" : "play_name.keyword"
            }
        }
    }
}

Als Ergebnis erhalten wir:

{
    "took": 35,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 111393,
        "max_score": 0,
        "hits": []
    },
    "aggregations": {
        "Popular plays": {
            "doc_count_error_upper_bound": 2763,
            "sum_other_doc_count": 73249,
            "buckets": [
                {
                    "key": "Hamlet",
                    "doc_count": 4244
                },
                {
                    "key": "Coriolanus",
                    "doc_count": 3992
                },
                {
                    "key": "Cymbeline",
                    "doc_count": 3958
                },
                {
                    "key": "Richard III",
                    "doc_count": 3941
                },
                {
                    "key": "Antony and Cleopatra",
                    "doc_count": 3862
                },
                {
                    "key": "King Lear",
                    "doc_count": 3766
                },
                {
                    "key": "Othello",
                    "doc_count": 3762
                },
                {
                    "key": "Troilus and Cressida",
                    "doc_count": 3711
                },
                {
                    "key": "A Winters Tale",
                    "doc_count": 3489
                },
                {
                    "key": "Henry VIII",
                    "doc_count": 3419
                }
            ]
        }
    }
}

Wir sehen also die 10 beliebtesten Werte für „play_name“. In der Dokumentation können Sie sich jederzeit ansehen, wie Sie Aggregationen mit mehr oder weniger Werten abrufen.

Wenn Sie mir soweit gefolgt sind, können Sie sich bestimmt den nächsten Schritt denken: kombinierte Aggregationen. Möglicherweise möchten wir wissen, wie viel Szenen, Akte und Zeilen unser Index enthält. Vielleicht interessieren uns diese Werte auch für einzelne Stücke. Dazu können wir Aggregationen innerhalb von Aggregationen verschachteln:

GET localhost:9200/shakespeare/_search
{
    "size":0,
    "aggs" : {
        "Total plays" : {
            "terms" : {
                "field" : "play_name.keyword"
            },
            "aggs" : {
                "Per type" : {
                    "terms" : {
                        "field" : "_type"
                     }
                }
            }
        }
    }
}

Hier ist ein Teil der Antwort:

    "aggregations": {
        "Total plays": {
            "doc_count_error_upper_bound": 2763,
            "sum_other_doc_count": 73249,
            "buckets": [
                {
                    "key": "Hamlet",
                    "doc_count": 4244,
                    "Per type": {
                        "doc_count_error_upper_bound": 0,
                        "sum_other_doc_count": 0,
                        "buckets": [
                            {
                                "key": "line",
                                "doc_count": 4219
                            },
                            {
                                "key": "scene",
                                "doc_count": 20
                            },
                            {
                                "key": "act",
                                "doc_count": 5
                            }
                        ]
                    }
                },
                ...

In Elasticsearch haben Sie viele verschiedene Aggregationen zur Auswahl: Aggregationen über das Ergebnis anderer Aggregationen, Metrikaggregationen wie etwa „cardinality“, Buckets-Aggregationen wie „terms“ usw. Es liegt an Ihnen, sich die Liste anzusehen und zu entscheiden, welche Aggregation sich am besten für den Anwendungsfall eignet, der Ihnen vorschwebt! Wie wäre es beispielsweise mit einer „Significant terms“-Aggregation für ungewöhnlich gewöhnliche Elemente?

Damit sind wir am Ende des zweiten Abschnitts angekommen. Bisher haben wir:

  1. die Bulk-API verwendet, um Shakespeare-Stücke hinzuzufügen.
  2. einfache Suchvorgänge ausgeführt und uns das generische Format für Abfragen mit der Abfrage-DSL angesehen.
  3. eine Leaf-Suche verwendet, um Text in einem Feld zu finden.
  4. zwei Textsuchen zu einer Verbundsuche kombiniert.
  5. eine zweite Verbundsuche vorgeschlagen.
  6. Tests für die verschiedenen Optionen im Anforderungstext vorgeschlagen.
  7. Aggregationen vorgestellt, zusammen mit einer kurzen Übersicht über Mappings und Feldtypen.
  8. berechnet, wie viele Stücke unser Datensatz enthält.
  9. diejenigen Stücke abgerufen, die in unserem Datensatz am häufigsten vorkommen.
  10. mehrere Aggregationen kombiniert, um herauszufinden, wie viele Akte, Szenen und Zeilen die zehn häufigsten Theaterstücke jeweils enthalten.
  11. eine nähere Auseinandersetzung mit den weiteren Aggregationen in Elastic vorgeschlagen.

Zusätzliche Tipps

In den bisherigen Übungen haben wir uns das Konzept von Typen in Elasticsearch oberflächlich angesehen. Typen sind letztendlich nur zusätzliche interne Felder: Ab Version 6 dürfen Indizes nur noch mit einem einzigen Typ erstellt werden, und ab Version 7 werden Typen höchstwahrscheinlich komplett entfernt. Weitere Informationen finden Sie in diesem Blogeintrag.

Fazit

In diesem Blogeintrag haben wir verschiedene Beispiele für den Einstieg in Elasticsearch verwendet.

Elasticsearch und der Elastic Stack haben noch viel (VIEL!) mehr zu bieten als das, was wir in diesem kurzen Artikel vorgestellt haben. Bevor wir zum Abschluss kommen, möchte ich noch das Thema Relevanz erwähnen. Elasticsearch beantwortet nicht nur die Frage „Erfüllt dieses Dokument meine Suchanfrage?“, sondern auch „Wie gut erfüllt dieses Dokument meine Suchanfrage?“. Zu diesem Zweck werden Suchergebnisse, die für die Abfrage besonders relevant sind, zuerst zurückgegeben. Die Dokumentation zu diesem Thema ist sehr ausführlich und enthält zahlreiche Beispiele.

Bevor Sie benutzerdefinierte Features implementieren, sollten Sie stets in der Dokumentation nachsehen, ob das Feature nicht bereits existiert und mühelos in Ihr Projekt eingebunden werden kann. Es ist gut möglich, dass Features oder Ideen, die Sie für hilfreich halten, bereits verfügbar sind, da sich unsere Entwicklungs-Roadmap stark an den Wünschen unserer Nutzer und Entwickler orientiert!

Features im Zusammenhang mit Authentifizierung, Zugriffskontrolle, Verschlüsselung und Audit sind bereits in Security enthalten. Überwachungsfunktionen für Ihren Cluster sind in Monitoring verfügbar. Falls Sie dynamische Felder in Ihren Ergebnissen erstellen möchten, können Sie dazu die Skriptfelder verwenden. Warnungen per E-Mail/Slack/Hipchat usw. können Sie mit Alerting erstellen. Für die Visualisierung von Daten und Aggregationen in Diagrammen stellen wir mit Kibana bereits eine umfangreiche Umgebung bereit. Für die Indexierung von Daten aus Datenbanken, Log-Dateien, Verwaltungswarteschlangen oder praktisch jeder anderen Quelle können Sie Logstash und Beats nutzen. Ganz egal, was Sie brauchen, die Lösung existiert höchstwahrscheinlich schon!