<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[ES|QL - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[ES|QL - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/de/search-labs/blog/category/esql</link>
    </image>
    <link>https://www.elastic.co/de/search-labs/blog/category/esql</link>
    <atom:link href="https://www.elastic.co/de/search-labs/rss/category/esql.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[de]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 20:55:20 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Elasticsearch ES|QL ermöglicht die Volltextsuche in Daten, die nie von Ihnen indiziert wurden.]]></title>
    <description><![CDATA[MATCH und TO_TEXT ermöglichen die Volltextsuche in Daten, die nie von Ihnen indiziert wurden. So können Sie berechnete Spalten, nicht zugeordnete Felder und Verbunddaten in ES|QL durchsuchen.]]></description>
    <content:encoded><![CDATA[<p>ES|QL MATCH führt jetzt eine Volltextsuche auf Daten aus, die Sie nie indexiert haben. Berechnete Spalten, nicht zugeordnete Felder, spontan zusammengestellte Zeichenfolgen, sogar Verbunddaten, die in S3 gespeichert sind. Die neue Funktion TO_TEXT weist ES|QL an, jede Zeichenfolge als analysierbaren Text zu behandeln, sodass MATCH Werte tokenisieren, Groß-/Kleinschreibung auflösen und Terme abgleichen kann, die nur für die Dauer einer Abfrage existieren. Das geht über die LIKE- und RLIKE-Mustererkennung hinaus, die die meisten Abfrage-Engines für nicht indexierte Zeichenfolgen anbieten: Es handelt sich um echte Analyse. Jetzt verfügbar in Elastic Cloud Serverless und als technische Vorschau in Elasticsearch 9.5.</p><h2>Wie MATCH und TO_TEXT die Volltextsuche in beliebigen ES|QL-Ausdrücken ermöglichen</h2><p>Beginnen wir mit einer Abfrage, die in Elasticsearch 9.4 unmöglich war und <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/eval">den EVAL-Befehl</a> verwendet:</p><p>In diesem Beispiel hat Summary keine Mapping- oder Analyzer-Konfiguration. Es ist auch mit keinem invertierten Index verbunden. Es existiert nur für die Dauer dieser Abfrage, kann jetzt aber trotzdem durchsucht werden. Das machen zwei Ergänzungen möglich.</p><p>Erstens akzeptiert <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/search-functions/match">MATCH</a> nun jeden Ausdruck als erstes Argument, nicht nur ein abgebildetes Feld. Dies umfasst Spalten, die von EVAL erzeugt werden, sowie Funktionsergebnisse, die inline verwendet werden. Es enthält auch nicht zugeordnete Felder, die direkt aus dem Originaldokument geladen wurden. Darüber hinaus werden in diesem neuen Anwendungsfall alle normalerweise von MATCH akzeptierten Datentypen unterstützt.</p><p>Der zweite Teil davon ist die neue <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/type-conversion-functions/to_text">TO_TEXT-Funktion</a>, die die erste ES|QL-Konvertierungsfunktion ist, die eine Ausgabe vom Typ Text erzeugt. Bisher konnten Textspalten nur aus indizierten zugeordneten Feldern stammen, und alle von ES|QL-Ausdrücken erzeugten Zeichenfolgen waren Schlüsselwortwerte statt Textwerte. Die Unterscheidung ist wichtig, weil MATCH die beiden unterschiedlich behandelt: Textwerte werden analysiert, während Keyword-Werte exakt verglichen werden, was der Umschreibung einer MATCH-Abfrage auf einem indexierten Schlüsselwortfeld in eine Termanfrage ähnelt. TO_TEXT(x) ist die Art, wie Siew ES|QL Folgendes sagen: <em>Behandle diese Zeichenfolge als Volltext</em>.</p><p>Dies wird als technische Vorschau in Elasticsearch 9.5 ausgeliefert und hat daher einige Einschränkungen:</p><ul><li><p>Es wird derzeit nur gefiltert. Ein MATCH-Ergebnis in einem Ausdruck trägt noch nicht zur Relevanzbewertung bei; nur Übereinstimmungen in indizierten Feldern wirken sich auf die Bewertung aus.</p></li><li><p>Abfrageoptionen wie Unschärfe und andere werden beim Abgleich eines Ausdrucks noch nicht unterstützt.</p></li><li><p>Der Laufzeittext wird mit dem Standard-Analyzer analysiert. Dies ist noch nicht konfigurierbar.</p></li></ul><p>Es wird daran gearbeitet, diese Einschränkungen zu beheben.</p><h2>Warum sollte man in ES|QL Volltextsuche statt LIKE oder RLIKE verwenden?</h2><p>ES|QL hatte bereits zwei Möglichkeiten, Zeichenfolgen ohne Index zu suchen: LIKE (Wildcard-Muster) und RLIKE (reguläre Ausdrücke). Beide funktionieren bei jedem Zeichenfolge-Ausdruck, daher ist es fair zu fragen, was MATCH hinzufügt. Die Antwort ist <a href="https://www.elastic.co/docs/manage-data/data-store/text-analysis">analysis</a>, eine fortgeschrittenere Suchmethode, die Techniken wie Stemming und Synonyme verwendet. Es verwendet auch eine Stoppwortbehandlung.</p><p>LIKE ist einfaches Substring-Matching, ohne jegliches Verständnis der Wörter, aus denen eine Zeichenfolge besteht. Nehmen wir beispielsweise an, Sie suchen nach Log-Meldungen über einen Fuchs:</p><p>„Fuchs in der Nähe des Hühnerstalls gesichtet“ wird aufgrund der Großschreibung nicht gefunden, während es „Von der Konkurrenz überlistet“ ein Treffer ist, obwohl das überhaupt nichts mit einem Fuchs zu tun hat. Das Verfahren versagt in beiden Richtungen: Es kommt zu falschen Negativbefunden bei der Großschreibung und zu falschen Positivbefunden bei innerhalb anderer Wörter verborgenen Teilzeichenfolgen.</p><p>Reguläre Ausdrücke können das Problem der Groß-/Kleinschreibung beheben, aber das Problem der Wortgrenzen wird schnell unübersichtlich. Hier ist ein Beispiel:</p><p>Und selbst das stimmt noch nicht. Der Fuchs am Ende eines Satzes, gefolgt von ! oder ?, ist ihm entgangen und es sagt nichts über Tabulatoren, Anführungszeichen oder Klammern aus. Mit jeder Korrektur wird das Muster länger, und die nächste Person, die die Abfrage liest, muss nachvollziehen, was das eigentlich passiert.</p><p>MATCH beseitigt das Problem, weil sowohl die Abfrage als auch der Wert durch einen <a href="https://www.elastic.co/docs/reference/text-analysis/analyzer-reference">Analyzer</a> laufen, der den Text in Kleinbuchstaben tokenisiert und dann Term für Term abgleicht:</p><p>Diese Abfrage passt zu Werten wie „Der schnelle braune Fuchs“ und „FUCHS in der Nähe des Hühnerstalls gesehen“, aber nicht „Von der Konkurrenz überlistet“ oder „FOXTROT-Protokoll aktiviert“, unabhängig von jeglicher Zeichensetzung um die Wörter. Selbstverständlich funktioniert das alles auch für Abfragen mit mehreren Begriffen, wie z. B. MATCH(TO_TEXT(message), „brauner Fuchs“), genau so, wie man es erwarten würde.</p><p>Es wird daran gearbeitet, die <a href="https://www.elastic.co/docs/reference/text-analysis/analysis-lang-analyzer">Nutzung der 36 dedizierten Sprachanalysatoren</a> zu ermöglichen, mit Unterstützung für natürliche Sprachen auf Daten, die nie indexiert oder kartiert wurden.</p><h2>Anwendungsfälle der Volltextsuche für unindexierte und nicht abgebildete Daten</h2><p>Die obigen Beispiele suchten Werte, die aus <a href="https://www.elastic.co/docs/manage-data/data-store/mapping">abgebildeten Feldern</a> berechnet wurden. Die interessantesten Anwendungsfälle für ES|QL MATCH bei Ausdrücken betreffen Daten, die zuvor überhaupt nicht durchsuchbar waren. Schauen wir uns einige Beispiele an.</p><h3>Wie kann man in ES|QL nach nicht zugeordneten Feldern suchen, ohne ein Mapping hinzuzufügen?</h3><p>Manchmal lässt man absichtlich ein Feld aus den Mappings weg, wie zum Beispiel eine ausführliche Stack-Trace oder eine rohe Anfrage-Nutzlast. Du könntest sogar einen Debug-Blob weglassen. Das Indexieren eines dieser Felder würde Speicherplatz auf der Festplatte und im Heap-Speicher des Dokuments beanspruchen und wäre für ein Feld, das man möglicherweise nur einmal pro Quartal abfragt, nicht lohnenswert.</p><p>Diese Entscheidung war immer endgültig, weil <a href="https://www.elastic.co/search-labs/blog/esql-unmapped-fields">nicht zugeordnete Felder</a> für Abfragen völlig unsichtbar waren. In Elasticsearch 9.5 können Sie mit SET unmapped_fields="load" bewirken, dass ES|QL nicht zugeordnete Felder direkt aus dem Quelldokument als Schlüsselwörter lädt. Anschließend wird der Ausdruck in TO_TEXT eingeschlossen, und nun können Sie eine Volltextsuche darauf ausführen:</p><p>Hier wurde stack_trace nie zugeordnet. Jeder Wert wird aus den Originaldokumenten abgerufen und direkt analysiert. Sie werden zeilenweise einander zugeordnet. Das ist echte Arbeit und wird niemals so schnell sein wie eine <a href="https://www.elastic.co/docs/manage-data/data-store/index-basics">invertierte</a> Index-Suche. Aber jetzt ist das Feld, das Sie nicht indexiert haben, nicht mehr undurchsuchbar. Sie können das Mapping für den Alltag klein halten und trotzdem die einmal im Quartal anstehende Frage beantworten, wenn es darauf ankommt.</p><h3>Volltextsuche in einem Stichwortfeld ohne Neuindizierung</h3><p>Keyword-Felder können vieles bewirken. Sie liefern exakte Abgleiche, schnelle Aggregationen und Sortierung, weshalb so viele Felder auf diese Weise zugeordnet werden. Die Mappings der Daten erfolgen jedoch erst, wenn sie eintreffen, und es kann leicht passieren, dass man am Ende etwas anderes mit den Daten machen möchte, als man ursprünglich beabsichtigt hatte. Vielleicht wurde „product_name“ als Keyword zugeordnet, weil die Dashboards darauf aggregieren, und nachdem ein Jahr Produktdaten eingegangen ist, möchte jemand innerhalb der Werte von „product_name“ suchen können.</p><p>Die alte Antwort war, das Mapping auf Text zu ändern (oder ein Multi-Feld hinzuzufügen) und alles neu zu indexieren. Das kann sowohl zeitaufwändig als auch kostspielig sein, und in vielen Fällen wollen sich die Nutzer einfach nicht darum kümmern. Die neue Antwort ist ein Funktionsaufruf:</p><p>TO_TEXT wandelt die Keyword-Werte spontan in Text um; daher analysiert MATCH sie, anstatt sie exakt zu vergleichen. So können Sie ein Schlüsselwort-Feld abfragen, ohne ein Mapping erstellen oder das Quelldokument neu zu indexieren. Wenn die Suche zu einer alltäglichen Anfrage wird, ist das Indizieren des Feldes als Text zwar immer noch der richtige langfristige Schritt, aber mit TO_TEXT erhalten Sie heute schon eine Antwort, ohne zusätzlichen Aufwand.</p><h3>Das gleiche Feld in Indizes mit unterschiedlichen Mappings durchsuchen</h3><p><a href="https://www.elastic.co/docs/reference/query-languages/esql/esql-multi-index">ES|QL kann viele Indizes umfassen</a>, und dasselbe Feld muss nicht immer in allen gleich aussehen. Wenn dasselbe Feld unterschiedliche Typen in verschiedenen Indizes hat, behandelt ES|QL es als Unionstyp, und eine Konvertierungsfunktion löst den Konflikt. Betrachten wir ein Beispiel, in dem das Message-Feld in der diesjährigen Indexvorlage den Typ „Text“ hat, in der letztjährigen Vorlage aber ein Keyword war:</p><p>Jeder Wert wird zur Abfragezeit analysiert, unabhängig davon, ob er aus dem Textindex oder dem Stichwortindex stammt. Die Keywordwerte aus den älteren Indizes werden wie alles andere tokenisiert und kleingeschrieben, sodass „connection reset“ unabhängig davon, in welchem Index es sich befindet, „Connection RESET by peer“ findet.</p><p>Ein weiterer interessanter Fall ist, wenn ein Feld nur in einem Index abgebildet wird, aber auch im anderen vorhanden (und nicht abgebildet):</p><p>Es gibt eine Nuance, die es wert ist, hier erwähnt zu werden. Wenn error_details in logs-2026, aber nicht in logs-2025 abgebildet ist, kann Elasticsearch diese Abfrage nicht auf <a href="https://lucene.apache.org/">Lucene</a> verschieben, da die Indizes, in denen das Feld nicht abgebildet ist, stillschweigend keine Übereinstimmungen liefern würden. Stattdessen stellt der Planer fest, dass das Feld möglicherweise nicht zugeordnet ist und wertet die gesamte MATCH Zeile für Zeile aus, unabhängig davon, woher die Zeilen stammen. Sie müssen nicht wissen, in welchem Ihrer Indizes das Feld zugeordnet ist; die Abfrage beantwortet einfach die Frage.</p><h2>Wie ES|QL Text zur Abfragezeit ohne invertierten Index analysiert</h2><p>Wenn ES|QL einen MATCH-Abgleich mit einem Ausdruck plant, analysiert es die Abfragezeichenfolge einmalig, im Voraus, in eine Reihe von Begriffen. Wie jede Zeile anschließend ausgewertet wird, hängt vom Typ des Ausdrucks ab:</p><p><strong>Ausdruckstyp</strong></p><p><strong>Verarbeitung</strong></p><p><strong>Übereinstimmendes Verhalten</strong></p><p>Text (über TO_TEXT)</p><p>Analyzer tokenisiert Werte in Kleinbuchstaben</p><p>Token-gegen-Token-Vergleich; eine Zeile gilt als Treffer, wenn ein Token einem Abfrageterm entspricht (ODER-Semantik)</p><p>Schlüsselwort, IP, Datum, numerisch</p><p>Keine Analyse; die Abfragekonstante einmal in den nativen Typ konvertiert</p><p>Exakter Vergleich pro Zeile</p><p>Beide Wege umgehen Lucene vollständig und bewerten Werte Zeile für Zeile. Der Nichttextpfad spiegelt genau das wider, was eine Match-Query tut, wenn sie an Lucene für diese Feldtypen delegiert wird, sodass die Semantik unabhängig davon konsistent bleibt, ob die Abfrage einen Index trifft.</p><p>Eine Suche mit invertiertem Index führt ihre Arbeit zur Ingest-Zeit durch und greift bei der Abfrage niemals auf nicht übereinstimmende Dokumente zu. Ein Laufzeit-Match führt diese Analyse zur Abfragezeit für jede Zeile durch, die sie erreicht. Die eine Methode ist schnell, weil die Arbeit bereits erledigt ist; die andere ist flexibel, weil die Daten überhaupt nicht indexiert werden müssen.</p><h2>Was kommt als Nächstes für die ES|QL-Volltextsuche</h2><p>Alles in diesem Beitrag ist der erste Teil eines größeren Vorhabens, die Suche in ES|QL auf alles anzuwenden, nicht nur auf das, was man vorher indexiert hat. Die zuvor genannten Einschränkungen werden aktiv bearbeitet und die Roadmap geht weiter:</p><ul><li><p><strong>Bewertung.</strong> Runtime-Matches tragen zu _score bei, sodass Sie nach Relevanz sortieren können, auch wenn die Daten nie indexiert wurden.</p></li><li><p><strong>MATCH_PHRASE</strong><strong> auf Ausdrücke.</strong> Bereits in Elastic Cloud Serverless verfügbar, und kommt im Elastic Stack in Version 9.6.</p></li><li><p><strong>Konfigurierbare Analysatoren.</strong> Analyzer-Unterstützung für MATCH und MATCH_PHRASE bei Ausdrücken, die Language Analyzer, Stemming und Synonyme zur Abfragezeit ermöglichen.</p></li><li><p><strong>Matchoptionen.</strong> Optionen wie Unschärfe und Operator für Laufzeitübereinstimmungen.</p></li><li><p><strong>Vektorsuche.</strong> Generieren von Einbettungen pro Zeile und Ausführen der k-Nearest-Neighbor-Methode (kNN) auf Laufzeit-dense_vector-Ausdrücken, wodurch die semantische Suche auch auf unindizierte Daten ausgeweitet wird.</p></li></ul><h2>Probieren Sie noch heute die ES|QL-Volltextsuche für Ausdrücke aus.</h2><p>Sie können die Laufzeitsuche noch heute ausprobieren. Es ist jetzt in Elastic Cloud Serverless verfügbar, wo neue ES|QL-Fähigkeiten zuerst erscheinen und als technische Vorschau in Elasticsearch 9.5 ausgeliefert werden. Beginnen Sie mit der <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/search-functions">Suchfunktionsreferenz</a> und prüfen Sie die <a href="https://www.elastic.co/docs/reference/query-languages/esql/limitations">ES|QL-Einschränkungsseite</a> für die aktuellen Grenzen. Es ist eine technische Vorschau, weil wir Ihr Feedback wollen: Wenn Sie nach etwas suchen, das nie indexiert wurde, und überrascht, sei es positiv oder negativ, <a href="https://www.elastic.co/de/community">würden wir gerne davon hören</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/full-text-search-unindexed-data</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/full-text-search-unindexed-data</guid>
    <category><![CDATA[ES|QL]]></category>
    <category><![CDATA[Mappings]]></category>
    <dc:creator><![CDATA[Kevin Corcoran,Ioana Tagirta]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a74e633d05585a8/6a730774b8c2e64c3ebe0fd4/image1.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Direkt zum Dashboard in unter einer Minute, fünfmal günstiger: KI-Dashboards und benutzerdefinierte Vega-Lite-Diagramme in Kibana]]></title>
    <description><![CDATA[Beschreiben Sie Ihre Kennzahlen in natürlicher Sprache, und der KI-Chat von Kibana generiert ES|QL-basierte Dashboards und Vega-Lite-Diagramme, von Streudiagrammen bis hin zu bedingter Formatierung und benutzerdefinierten Tooltips.]]></description>
    <content:encoded><![CDATA[<p>Der <a href="https://www.elastic.co/docs/explore-analyze/ai-features/agent-builder/chat">KI-Chat</a> von Kibana erstellt jetzt anhand eines natürlichsprachigen Prompts in weniger als einer Minute vollständige, auf der <a href="https://www.elastic.co/docs/explore-analyze/visualize/esorql">Elasticsearch-Abfragesprache (ES|QL) basierende</a> Dashboards. Allgemein verfügbar (GA) wird dies in Elastic 9.5 (<a href="https://www.elastic.co/de/search-labs/blog/ai-dashboard-generation-elastic-agent-kibana">technische Vorschau in Version 9.4</a>) mit einer Fehlerbehebung, die fehlgeschlagene Abfragen erneut versucht, fünfmal niedrigeren ES|QL-Generierungskosten durch gestuftes Modellrouting und interaktiven Filtersteuerungen. Diese Version ermöglicht außerdem die Erstellung von <a href="https://www.elastic.co/docs/explore-analyze/visualize/custom-visualizations-with-vega">Vega-Lite-Diagrammen</a> mithilfe natürlicher Sprache, mit Streudiagrammen, Boxplots, bedingter Formatierung und benutzerdefinierten Tooltips, die man normalerweise manuell in JSON programmieren müsste.</p><h2>Was ist neu bei der Erstellung von KI-Dashboards in Kibana?</h2><p><strong>Funktionalität</strong></p><p><strong>Technische Vorschau (9.4)</strong></p><p><strong>GA (9.5)</strong></p><p>Fehlerbehandlung</p><p>Kein Wiederholungsversuch bei fehlgeschlagenen ES|QL-Abfragen</p><p>Automatischer, bis zu dreimaliger erneuter Versuch mit Abfrageprüfung und Anpassung</p><p>ES|QL-Generierungskosten</p><p>Alle Abfragen werden über das primäre Modell weitergeleitet</p><p>Gestaffelte Modellrouten, bis zu fünfmal günstiger</p><p>Zeitbereich</p><p>Festgelegtes Standardfenster</p><p>Automatische Auswahl basierend auf der Daten-Zeit-Verteilung</p><p>Filtersteuerungen</p><p>Nein</p><p>Automatisch für die relevantesten Felder</p><p>Vega-Lite-Diagramme</p><p>Nein</p><p>Erstellung in natürlicher Sprache, mit Streudiagrammen, Boxplots, bedingter Formatierung und benutzerdefinierten Tooltips</p><p>Diagrammbearbeitung</p><p>Nein</p><p>Bestehende Vega-Lite-Panels können in natürlicher Sprache bearbeitet werden</p><h3>Automatische Fehlerbehebung bei der KI-Dashboard-Generierung</h3><p>In der technischen Vorschau wurden fehlgeschlagene ES|QL-Abfragen vom Agenten nicht wiederholt. In Version 9.5 werden Abfragefehler erkannt und die Abfrage bis zu dreimal wiederholt, wobei jeder Fehler untersucht und die Abfrage angepasst wird, bevor der Agent aufgibt. In der Praxis beseitigt dies die meisten Probleme mit leeren Panels und erzeugt Dashboards, die schon beim ersten Versuch korrekt gerendert werden.</p><h3>Warum ist die Erstellung von KI-Dashboards in Elastic 9.5 günstiger?</h3><p>Nicht jeder Schritt bei der Dashboard-Erstellung erfordert das gleiche Maß an Argumentation. In Version 9.5 erfolgt die ES|QL-Generierung standardmäßig über ein leichteres Modell und greift nur bei Bedarf auf das primäre Modell zurück. Wenn Ihr <a href="https://www.elastic.co/docs/explore-analyze/ai-features/agent-builder/connectors">Connector</a> Claude Opus 4.8 von Anthropic verwendet, bedeutet das fünfmal günstigere Kosten für die ES|QL-Generierung in allen Panels.</p><h3>Automatische Zeitbereichsauswahl auf der Grundlage Ihrer Daten</h3><p>Dashboards sind nur dann nützlich, wenn sie den richtigen Datenausschnitt anzeigen. Der Agent wendet nun eine verbesserte Logik an, um einen für die abgefragten Daten sinnvollen Zeitbereich auszuwählen, es sei denn, der Nutzer fragt nach einem bestimmten Zeitbereich. Er berücksichtigt die Zeitverteilung der Daten und passt sich entsprechend an, seien es die letzte Stunde für einen Live-Vorfall oder die letzten 90 Tage für eine Trendanalyse, anstatt standardmäßig auf ein festes Zeitfenster zurückzugreifen.</p><h3>Automatische Filtersteuerungen auf KI-generierten Dashboards</h3><p>Die Erstellung von Dashboards unterstützt nun Steuerelemente; das heißt interaktive Filter, mit denen die Betrachter ein Dashboard nach Feldwerten eingrenzen können, ohne die zugrunde liegenden Abfragen bearbeiten zu müssen. Beim Generieren eines Dashboards fügt der Agent am oberen Rand automatisch Steuerelemente für die relevantesten Filterfelder hinzu.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4a5520e66ae76001/6a719a218a155220ed6498e7/image3.png" alt="Kibana AI chat generating an ES|QL-backed host metrics dashboard with automatic filter controls in 71 seconds" /><h2>Vega-Lite-Diagramme aus natürlicher Sprache: Diagrammtypen und Formatierung jenseits der Standardeinstellungen</h2><p><a href="https://vega.github.io/vega/">Vega</a> und <a href="https://vega.github.io/vega-lite/examples/">Vega-Lite</a> unterstützen in Kibana eine breite Palette von Diagrammtypen und Anpassungen. Mit Version 9.5 können Sie sie aus einfacher Sprache erstellen und müssen den Code nicht selbst schreiben. </p><h3>Streudiagramme, Boxplots und weitere Diagrammtypen in Vega-Lite</h3><p>Streudiagramme, Boxplots, facettierte Small Multiples, Blasendiagramme und Kompositionsdiagramme (z. B. Histogramme, kombiniert mit Heatmaps) sowie viele andere werden von <a href="https://vega.github.io/vega-lite/examples/">Vega-Lite</a> unterstützt. Ein Prompt wie <em>Zeig mir ein Streudiagramm zu Reaktionszeit vs. Anfragegröße, farbig nach Dienstprogrammname</em> erzeugt ein Vega-Lite-Panel mit den richtigen Datenzuordnungen. Die Diagramme verwenden die Standardfarbpaletten von Kibana, um sich harmonisch in das restliche Dashboard einzufügen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf1651fe7ac903d47/6a719a49f124649f746fc1b4/image5.png" alt="Kibana dashboard with four Vega-Lite charts: box plot, bubble chart, faceted small multiples, and heatmap." /><h3>Bedingte Formatierung, benutzerdefinierte Tooltips und Beschriftungen auf Standarddiagrammen</h3><p>Selbst bei Diagrammtypen, die in einem Dashboard bereits systemeigen sind, zum Beispiel Balkendiagramme, Liniendiagramme oder Flächendiagramme, benötigen Sie manchmal mehr Kontrolle, als die Standardfunktionen bieten. Vega-Lite schließt diese Lücke über den Chat. Zu den Beispielen gehören:</p><ul><li><p><strong>Bedingte Farbformatierung:</strong> Datenpunkte oberhalb eines Schwellenwerts können farbig anders dargestellt werden; beispielsweise werden Datenpunkte in einem Liniendiagramm oder in Balkendiagrammen rot eingefärbt, wenn eine Kennzahl über das Service Level Objective (SLO) hinausgeht. Bitten Sie den Agenten etwa: <em>Färbe alle Punkte über 500 ms für mein Liniendiagramm rot ein.</em> </p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc1211784e9033557/6a719a6ab966e1736163d7d1/image1.png" alt="Vega-Lite line and bar charts in Kibana with conditional colour formatting showing data points above a threshold in red" /><p></p></li><li><p><strong>Individuelle Markierungen und Beschriftungen:</strong> Fügen Sie Emojis, Symbole oder Inline-Textbeschriftungen zu Datenpunkten hinzu, um den Status auf einen Blick zu erkennen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte3c59c3748484bc1/6a719aa02888394fdc07bac1/image2.png" alt="Lite horizontal bar chart in Kibana with emoji flag labels and custom tooltip showing requests by country" /><p></p></li><li><p><strong>Individuelle Tooltips:</strong> Reichern Sie Hover-Zustände mit zusätzlichen Metriken, Kontext oder berechneten Werten an, die nicht Teil der Diagrammachsen sind. Formulieren Sie etwas wie <em>Füge einen Tooltip hinzu, der die Gesamtzahl der Datensätze und den Prozentsatz pro Balkendiagramm anzeigt.</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt43f241f4382b5b90/6a719ab7ded0cf3367f49275/image4.png" alt="Vega-Lite stacked bar chart in Kibana with custom tooltip showing total records and percentage of total by extension" /><p></p></li></ul><p>Das funktioniert auch bei der Bearbeitung vorhandener Vega-Charts. Wenn Sie ein Vega-Lite-Panel haben, das eine Anpassung wie z. B. das Ändern einer Farbskala, das Anpassen einer Achse oder ein Umschalten des Markierungstyps benötigt, beschreiben Sie die Änderung im Chat, anstatt sich in den JSON-Code einzuarbeiten.</p><h2>So haben wir die Vega-Lite-Generierung in natürlicher Sprache in Kibana entwickelt</h2><p>Das Generieren eines Vega-Lite-Diagramms aus einem Satz heraus ist kein einmaliger Prompt à la <em>Bitte das Modell um JSON</em>. Wir haben eine kleine agentenbasierte Pipeline aufgebaut, die natürliche Sprachabsicht in ein validiertes, datenbasiertes Diagramm umsetzt.</p><p>Wenn eine Anfrage eingeht, prüft der Agent zunächst, ob Vega-Lite die richtige Lösung ist. Für Vega-Lite-Anfragen verankert er die Visualisierung in einer echten ES|QL-Abfrage bei Elasticsearch und verwendet dann ein Modell, um den Vega-Lite-Code zu generieren. Vor dem Rendern durchläuft das Ergebnis eine Normalisierungsschicht, die das Schema korrigiert und die kanonische Abfrage bindet. Er wendet außerdem rendersichere Umwandlungen an. </p><p>Einige wenige Designentscheidungen machen diesen Workflow zuverlässig:</p><ul><li><p><strong>Eingetippter Toolaufruf</strong>: Die Diagrammerstellung ist ein strukturierter Tool-Aufruf und kein Vega-Lite, das in die Konversation eingefügt wird.</p></li><li><p><strong>Beschränkte Generierung</strong>: Das Modell erzeugt Vega-Lite-Code innerhalb eines definierten Schemas, was die Ausgabe vorhersehbarer und leichter validierbar macht.</p></li><li><p><strong>Kuratierte Beispiele:</strong> Strukturelle Muster wie Facetten, geschichtete Markierungen und Heatmaps bieten Orientierung, ohne die zugrunde liegenden Daten zu kopieren.</p></li><li><p><strong>Ausführungs- und Verifikationsschleifen</strong>: Abfragen werden vor der Diagrammerstellung ausgeführt, und Validierungsfehler lösen Korrekturversuche für die ES|QL-Generierung aus.</p></li></ul><h2>Testen Sie die Erstellung von KI-Dashboards und Vega-Lite-Diagrammen in Kibana</h2><p>Um die Erstellung von Dashboards mit natürlicher Sprache und Vega-Lite-Diagramme auszuprobieren, aktualisieren Sie auf <strong>Elastic 9.5</strong> (oder <a href="https://cloud.elastic.co/registration">starten eine kostenlose Testversion</a>) und öffnen den <strong>Chat</strong> in Kibana. Bitten Sie das System anschließend, aus Ihren Daten ein Dashboard zu erstellen. Bei Vega-Lite können Sie versuchen, einen Diagrammtyp anzufordern, den Sie schon immer einmal erstellen wollten, zum Beispiel ein Streudiagramm oder ein Blasendiagramm. Wenn das Ergebnis nicht ganz stimmt, sagen Sie dem Agenten, was er ändern soll. Er wiederholt den Vorgang dann entsprechend.</p><p>Dafür ist eine Enterprise-Lizenz erforderlich. <a href="https://www.elastic.co/docs/explore-analyze/ai-features/agent-builder/chat#get-started">Erste Schritte</a>.</p><p><em>Die Entscheidung über die Veröffentlichung der in diesem Blogeintrag beschriebenen Leistungsmerkmale und Features sowie deren Zeitpunkt liegt allein bei Elastic. Es ist möglich, dass noch nicht verfügbare Leistungsmerkmale oder Features nicht rechtzeitig oder überhaupt nicht veröffentlicht werden.</em></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/ai-dashboards-kibana-vega-lite</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/ai-dashboards-kibana-vega-lite</guid>
    <category><![CDATA[Kibana]]></category>
    <category><![CDATA[ES|QL]]></category>
    <dc:creator><![CDATA[Marta Bondyra,Teresa Alvarez Soler]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt54406ad0378bc5fc/6a7199ffed03ccee0dac9d7c/image6.png" length="0" type="image/png"/>
    <pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[LINQ to Elasticsearch ES|QL: C# schreiben, Elasticsearch abfragen]]></title>
    <description><![CDATA[Erkundung des neuen LINQ to Elasticsearch ES|QL-Providers im Elasticsearch .NET-Client, mit dem Sie C#-Code schreiben können, der automatisch in ES|QL-Abfragen übersetzt wird.]]></description>
    <content:encoded><![CDATA[<p>Ab <strong>v9.3.4</strong> und <strong>v8.19.18</strong> enthält der Elasticsearch .NET-Client einen <a href="https://learn.microsoft.com/en-us/dotnet/csharp/linq/">Language Integrated Query (LINQ)</a>-Provider, der C# LINQ-Ausdrücke in die <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html">Elasticsearch Query Language (ES|QL)</a>-Abfragen zur Laufzeit übersetzt. Anstatt ES|QL-Zeichenfolgen von Hand zu schreiben, stellen Sie Abfragen mit <code>Where</code>, <code>Select</code>, <code>OrderBy</code>, <code>GroupBy</code> und anderen Standardoperatoren zusammen. Der Anbieter kümmert sich um die Übersetzung, Parametrisierung und Deserialisierung der Ergebnisse, einschließlich des zeilenweisen Streamings, das die Speichernutzung unabhängig von der Größe der Ergebnismenge konstant hält.</p><h2>Ihre erste Abfrage</h2><p>Definieren Sie zunächst ein einfaches altes CLR-Objekt (POCO), das auf Ihren Elasticsearch-Index abgebildet wird. Eigenschaftsnamen werden über Standardattribute <code>System.Text.Json</code> , wie z. B. <code>[JsonPropertyName]</code>, oder über ein konfiguriertes <code>JsonNamingPolicy</code> in ES|QL-Spaltennamen aufgelöst. Die gleichen Regeln für <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/dotnet/source-serialization">die Quellenserialisierung</a>, die für den Rest des Clients gelten, gelten auch hier.</p>using System.Text.Json.Serialization;

public class Product
{
    [JsonPropertyName("product_id")]
    public string Id { get; set; }

    public string Name { get; set; }

    public string Brand { get; set; }

    [JsonPropertyName("price_usd")]
    public double Price { get; set; }

    [JsonPropertyName("in_stock")]
    public bool InStock { get; set; }
}<p>Nachdem der Typ festgelegt wurde, sieht eine Abfrage folgendermaßen aus:</p>var minPrice = 100.0;
var brand = "TechCorp";

await foreach (var product in client.Esql.QueryAsync&lt;Product&gt;(q =&gt; q
    .From("products")
    .Where(p =&gt; p.InStock &amp;&amp; p.Price &gt;= minPrice &amp;&amp; p.Brand == brand)
    .OrderByDescending(p =&gt; p.Price)
    .Take(10)))
{
    Console.WriteLine($"{product.Name}: ${product.Price}");
}<p>Der Anbieter übersetzt dies in folgende ES|QL:</p><p>Ein paar Details, die zu beachten sind:</p><ul><li><p><strong>Namensauflösung der Eigenschaften:</strong> <code>p.Price</code> wird aufgrund des Attributs <code>[JsonPropertyName]</code> zu <code>price_usd</code> , und <code>p.Brand</code> wird gemäß der Standard-CamelCase-Namenskonvention zu <code>brand</code> .</p></li><li><p><strong>Parametererfassung:</strong> Die C#-Variablen <code>minPrice</code> und <code>brand</code> werden als benannte Parameter erfasst (<code>?minPrice</code>, <code>?brand</code>). Sie werden separat von der Abfragezeichenfolge im JSON-Payload gesendet, was Injektionen verhindert und serverseitiges Abfrageplan-Caching ermöglicht.</p></li><li><p><strong>Streaming:</strong> <code>QueryAsync&lt;T&gt;</code> gibt<code>IAsyncEnumerable&lt;T&gt;</code> zurück. Zeilen werden einzeln materialisiert, sobald sie von Elasticsearch eintreffen.</p></li></ul><p>Sie können auch die generierte Abfrage und ihre Parameter inspizieren, ohne sie auszuführen:</p>var query = client.Esql.CreateQuery&lt;Product&gt;()
    .Where(p =&gt; p.InStock &amp;&amp; p.Price &gt;= minPrice &amp;&amp; p.Brand == brand)
    .OrderByDescending(p =&gt; p.Price)
    .Take(10);

Console.WriteLine(query.ToEsqlString());
// FROM products | WHERE (in_stock == true AND price_usd &gt;= 100) | SORT price_usd DESC | LIMIT 10

Console.WriteLine(query.ToEsqlString(inlineParameters: false));
// FROM products | WHERE (in_stock == true AND price_usd &gt;= ?minPrice AND brand == ?brand) | SORT price_usd DESC | LIMIT 10

var parameters = query.GetParameters();
// { "minPrice": 100.0, "brand": "TechCorp" }<h2>Wie funktioniert das? Eine kurze LINQ-Auffrischung</h2><p>Der Mechanismus, der LINQ-Anbieter ermöglicht, ist die Unterscheidung zwischen <code>IEnumerable&lt;T&gt;</code> und <code>IQueryable&lt;T&gt;</code>.</p><p>Wenn Sie<code>.Where(p =&gt; p.Price &gt; 100)</code> auf einem <code>IEnumerable&lt;T&gt;</code>aufrufen, kompiliert die Lambda zu einem <code>Func&lt;Product, bool&gt;</code>, einem regulären Delegierten, den die Laufzeit während des Prozesses ausführt. Dies ist LINQ-to-Objects.</p><p>Wenn Sie dieselbe Methode auf einem <code>IQueryable&lt;T&gt;</code>aufrufen, umwickelt der C#-Compiler stattdessen das Lambda in einem <code>Expression&lt;Func&lt;Product, bool&gt;&gt;</code> . Dies ist eine Datenstruktur, die die <em>Struktur</em> des Codes repräsentiert und nicht seine ausführbare Form. Der Ausdrucksbaum kann zur Laufzeit inspiziert, analysiert und in eine andere Sprache übersetzt werden.</p>// IEnumerable: the lambda is a compiled delegate
IEnumerable&lt;Product&gt; local = products.Where(p =&gt; p.Price &gt; 100);

// IQueryable: the lambda is an expression tree, a data structure
IQueryable&lt;Product&gt; remote = queryable.Where(p =&gt; p.Price &gt; 100);<p>Die <code>IQueryProvider</code> Schnittstelle ist der Erweiterungspunkt. Jeder Anbieter kann <code>CreateQuery&lt;T&gt;</code> und <code>Execute&lt;T&gt;</code> implementieren, um diese Ausdrucksbäume in eine Zielsprache zu übersetzen. Entity Framework verwendet dies, um SQL auszugeben. Der LINQ to ES|QL-Anbieter verwendet es, um ES|QL zu emittieren.</p><p>Der Ausdrucksbaum für die obige Abfrage sieht wie folgt aus:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt521838e8b9c36649/6a1705b1839dfa5f40dcfdfe/f864cd18a390831f8d28503a29b5835efb1842f7-1000x720.png" alt="Ausdrucksbaum für die Beispielabfrage." /><p><em>Ausdrucksbaum für die Beispielabfrage.</em></p><p>Der Baum ist von innen nach außen verschachtelt: <code>Take</code> umschließt <code>OrderByDescending</code>, welches <code>Where</code> umschließt, welches <code>From</code> umschließt, welches die Wurzel <code>EsqlQueryable&lt;Product&gt;</code> Konstante umschließt. Das <code>Where</code> -Prädikat ist selbst ein Teilbaum von <code>BinaryExpression</code> Knoten für die Operatoren <code>&amp;&amp;</code>, <code>&gt;=</code>, und <code>==</code> , mit <code>MemberExpression</code> Blättern für Eigenschaften-Zugriffe und Abschluss-Erfassungen für die Variablen <code>minPrice</code> und <code>brand</code> . Dies ist die Datenstruktur, die der Provider durchläuft, um das endgültige ES|QL zu erzeugen.</p><h2>Unter der Haube: Die Übersetzungspipeline</h2><p>Der Weg von einem LINQ-Ausdruck zu den Abfrageergebnissen folgt einer sechsstufigen Pipeline:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt930670a505dd61ea/6a1705b3b339d58a54769ecf/2a2c772b63d720f61fc9a28b2f85668fa2db8d38-1999x1036.png" alt="Überblick über die Übersetzungspipeline." /><p><em>Überblick über die Übersetzungspipeline.</em></p><h3>1. Erfassung des Ausdrucksbaums</h3><p>Wenn man <code>.Where()</code>, <code>.OrderBy()</code>, <code>.Take()</code> und andere Operatoren auf einem <code>IQueryable&lt;T&gt;</code> verkettet, erstellt die Standard-LINQ-Infrastruktur einen Ausdrucksbaum. <code>EsqlQueryable&lt;T&gt;</code> implementiert <code>IQueryable&lt;T&gt;</code> und delegiert an <code>EsqlQueryProvider</code>.</p><h3>2. Übersetzung</h3><p>Wenn die Abfrage ausgeführt wird (durch Enumerieren, Aufrufen von <code>ToList()</code> oder Verwenden von <code>await foreach)</code>), durchläuft <code>EsqlExpressionVisitor</code> den Ausdrucksbaum von innen nach außen. Es sendet jeden LINQ-Methodenaufruf an einen spezialisierten Besucher:</p><p>Besucher</p><p>Übersetzt</p><p>In</p><p>WhereClauseVisitor</p><p>.Where(predicate)</p><p>WHERE-Bedingung</p><p>SelectProjectionVisitor</p><p>.Select(selector)</p><p>EVAL + KEEP + RENAME</p><p>GroupByVisitor</p><p>.GroupBy().Select()</p><p>STATISTIKEN ... NACH</p><p>OrderByVisitor</p><p>.OrderBy() / .ThenBy()</p><p>SORT field [ASC\|DESC]</p><p>EsqlFunctionTranslator</p><p>EsqlFunctions.*, Math.*, string methods</p><p>80+ ES|QL functions</p><p>Bei der Übersetzung werden in Ausdrücken referenzierte C#-Variablen als benannte Parameter erfasst.</p><h3>3. Abfragemodell</h3><p>Die Besucher produzieren nicht direkt Zeichenfolgen. Stattdessen produzieren sie <code>QueryCommand</code> Objekte, eine unveränderliche Zwischenrepräsentation. Ein <code>FromCommand</code>, ein <code>WhereCommand</code>, ein <code>SortCommand</code> und ein <code>LimitCommand</code>, jeweils einen ES|QL-Verarbeitungsbefehl repräsentierend. Diese werden in einem <code>EsqlQuery</code> Modell gesammelt.</p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt788c9936976f2f62/6a1705b50e2e4910da419ff0/2adc349b6cf655b96b7b3e826a134e8a17fe42fd-1999x1036.png" alt="Abfragemodell und Befehlsmuster." /><p><em>Abfragemodell und Befehlsmuster.</em></p><p>Dieses Zwischenmodell ist vom Ausdrucksbaum und vom Ausgangsformat entkoppelt. Es kann inspiziert, abgefangen (über <code>IEsqlQueryInterceptor</code>) oder vor der Formatierung modifiziert werden.</p><h3>4. Formatierung</h3><p><code>EsqlFormatter</code> besucht jede <code>QueryCommand</code> in der richtigen Reihenfolge und erstellt die finale ES|QL-Zeichenfolge. Jeder Befehl wird zu einer Zeile, getrennt durch den Pipe-Operator (|), den ES|QL zur Verkettung von Verarbeitungsbefehlen verwendet. Bezeichner, die Sonderzeichen enthalten, werden automatisch mit Backticks versehen.</p><h3>5. Ausführung</h3><p>Die formatierte ES|QL-Zeichenfolge und erfasste Parameter werden als JSON-Payload an den <code>/_query</code> -Endpunkt von Elasticsearch gesendet. Die Schnittstelle <code>IEsqlQueryExecutor</code> abstrahiert die Transportschicht, an der die geschichtete Paketarchitektur zum Tragen kommt.</p><h3>6. Materialisierung</h3><p><code>EsqlResponseReader</code> streamt die JSON-Reaktion, ohne das gesamte Ergebnis-Set in den Speicher zu puffern. Ein <code>ColumnLayout</code> -Baum, der einmal pro Abfrage vorab berechnet wird, ordnet flache ES|QL-Spaltennamen (wie <code>address.street</code>, <code>address.city</code>) verschachtelten POCO-Eigenschaften zu. Jede Zeile wird zu einer <code>T</code> -Instanz zusammengestellt und einzeln über <code>IEnumerable&lt;T&gt;</code> oder <code>IAsyncEnumerable&lt;T&gt;</code> zurückgegeben.</p><h2>Die mehrschichtige Architektur</h2><p>Die LINQ-to-ES|QL-Funktionalität ist auf drei Pakete aufgeteilt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt662bd0dd8861b6b6/6a1705b7a929cf7086ae08a2/41b8aae860ecdc2480edcb1c1d4cc9b03cfb78c9-1999x1036.png" alt="Paketarchitektur." /><p><em>Paketarchitektur.</em>
<a href="https://www.nuget.org/packages/Elastic.Esql"><strong><code>Elastic.Esql</code></strong></a> ist die reine Übersetzungsmaschine. Es hat keine HTTP-Abhängigkeiten und enthält die Expression Visitors, das Abfragemodell, den Formatter und den Response Reader. Sie können es eigenständig verwenden, um ES|QL-Abfragen ohne Elasticsearch-Verbindung zu erstellen und zu inspizieren, was für Tests, Abfrageprotokollierung oder den Aufbau einer eigenen Ausführungsschicht nützlich ist.</p>// Translation-only: no Elasticsearch connection needed
var provider = new EsqlQueryProvider();
var query = new EsqlQueryable&lt;Product&gt;(provider)
    .From("products")
    .Where(p =&gt; p.InStock)
    .OrderByDescending(p =&gt; p.Price);

Console.WriteLine(query.ToEsqlString());
// FROM products | WHERE in_stock == true | SORT price_usd DESC<p><a href="https://www.nuget.org/packages/Elastic.Clients.Esql"><strong><code>Elastic.Clients.Esql</code></strong></a> ist ein leichter, eigenständiger ES|QL-Client. Es fügt die HTTP-Ausführung über <code>Elastic.Esql</code> mittels <code>Elastic.Transport</code> hinzu. Wenn Ihre Anwendung nur ES|QL und keine der anderen Elasticsearch-APIs benötigt, ist dies die Option mit den geringsten Abhängigkeiten.</p><p><a href="https://www.nuget.org/packages/Elastic.Clients.Elasticsearch"><strong><code>Elastic.Clients.Elasticsearch</code></strong></a> ist der vollständige Elasticsearch.NET-Client. Es baut außerdem auf <code>Elastic.Esql</code> auf und stellt den LINQ-Provider über den Namespace <code>client.Esql</code> bereit. Dies ist der empfohlene Einstieg für die meisten Anwendungen.</p><p>Beide Ausführungsschicht-Pakete bieten ihre eigene Implementierung von <code>IEsqlQueryExecutor</code>, der Strategieschnittstelle, die Übersetzung und Transport miteinander verbindet.</p><p>Alle drei Pakete sind mit Native AOT kompatibel, wenn sie mit einem quellgenerierten <code>JsonSerializerContext</code> verwendet werden. Für den vollständigen Client siehe die <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/dotnet/source-serialization#native-aot">Native AOT-Dokumentation</a>.</p><h2>Über die Grundlagen hinaus</h2><p>Das obige Beispiel umfasste das Filtern, Sortieren und Paginieren. Der Anbieter unterstützt ein breiteres Spektrum an Operationen.</p><h3>Aggregationen</h3><p><code>GroupBy</code>, kombiniert mit Aggregatfunktionen in <code>Select</code>, übersetzt in ES|QL <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/stats-by"><code>STATS ... BY</code></a>:</p>var stats = client.Esql.Query&lt;Product, object&gt;(q =&gt; q
    .GroupBy(p =&gt; p.Brand)
    .Select(g =&gt; new
    {
        Brand = g.Key,
        Count = g.Count(),
        AvgPrice = g.Average(p =&gt; p.Price),
        MaxPrice = g.Max(p =&gt; p.Price)
    }));

// -&gt; FROM products | STATS COUNT(*), AVG(price_usd), MAX(price_usd) BY brand<h3>Projektionen</h3><p><code>Select</code>, mit anonymen Typen erzeugt die Befehle <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/eval"><code>EVAL</code></a>, <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/keep"><code>KEEP</code></a> und <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/rename"><code>RENAME</code></a>:</p>var query = client.Esql.CreateQuery&lt;Product&gt;()
    .Select(p =&gt; new { ProductName = p.Name, p.Price, p.InStock });

// -&gt; FROM products | KEEP name, price_usd, in_stock | RENAME name AS ProductName<h3>Umfassende Funktionsbibliothek</h3><p>Über 80 ES|QL-Funktionen sind über die <code>EsqlFunctions</code> -Klasse verfügbar und decken Datum/Uhrzeit, Zeichenfolgen, Mathematik, IP, Musterabstimmung und Wertung ab. Die Standardmethoden <code>Math.*</code> und <code>string.*</code> werden ebenfalls übersetzt:</p>.Where(p =&gt; p.Name.Contains("Pro"))       // -&gt; WHERE name LIKE "*Pro*"
.Where(p =&gt; EsqlFunctions.CidrMatch(      // -&gt; WHERE CIDR_MATCH(ip, "10.0.0.0/8")
    p.IpAddress, "10.0.0.0/8"))<h3>LOOKUP JOIN</h3><p>Indexübergreifende Suchvorgänge werden in ES|QL <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/lookup-join"><code>LOOKUP JOIN</code></a> übersetzt:</p>var enriched = client.Esql.Query&lt;Product, object&gt;(q =&gt; q
    .LookupJoin&lt;Product, CategoryLookup, string, object&gt;(
        "category-lookup-index",
        product =&gt; product.Id,
        category =&gt; category.CategoryId,
        (product, category) =&gt; new { product.Name, category!.CategoryLabel }));<h3>Raw ES|QL Umgehungsmöglichkeit</h3><p>Für ES|QL-Features, die vom LINQ-Anbieter noch nicht unterstützt werden, können Sie Rohfragmente anfügen:</p>var results = client.Esql.Query&lt;Product&gt;(q =&gt; q
    .Where(p =&gt; p.InStock)
    .RawEsql("| EVAL discounted = price_usd * 0.9"));<h3>Serverseitige asynchrone Abfragen</h3><p>Bei langlaufenden Abfragen sollten diese zur Hintergrundverarbeitung auf dem Server eingereicht werden:</p>await using var asyncQuery = await client.Esql.SubmitAsyncQueryAsync&lt;Product&gt;(
    q =&gt; q.Where(p =&gt; p.InStock),
    asyncQueryOptions: new EsqlAsyncQueryOptions
    {
        WaitForCompletionTimeout = TimeSpan.FromSeconds(5),
        KeepAlive = TimeSpan.FromMinutes(10)
    });

await asyncQuery.WaitForCompletionAsync();
await foreach (var product in asyncQuery.AsAsyncEnumerable())
    Console.WriteLine(product.Name);<p>Serverseitige asynchrone Abfragen sind besonders nützlich für langlaufende analytische Abfragen / die Verarbeitung großer Datensätze, die die typischen Timeout-Schwellenwerte überschreiten könnten, oder in Timeout-sensiblen Umgebungen mit Load-Balancern, API-Gateways oder Proxys, die strikte HTTP-Timeouts durchsetzen. Asynchrone Abfragen vermeiden Verbindungsabbrüche, indem die Übermittlung von dem Abruf der Ergebnisse entkoppelt wird.</p><h2>Erste Schritte</h2><p>LINQ to ES|QL ist verfügbar ab:</p><ul><li><p><strong>Elastic.Clients.Elasticsearch v9.3.4</strong> (9.x branch)</p></li><li><p><strong>Elastic.Clients.Elasticsearch v8.19.18</strong> (8.x Branch)</p></li></ul><p>Installation über NuGet:</p><p><code>dotnet add package Elastic.Clients.Elasticsearch</code></p><p>Die Einstiegspunkte befinden sich auf <code>client.Esql</code>:</p><p>Methode</p><p>Rückgaben</p><p>Anwendungsfall</p><p>Query&lt;T&gt;(...)</p><p>IEnumerable&lt;T&gt;</p><p>Synchrone Ausführung</p><p>QueryAsync&lt;T&gt;(...)</p><p>IAsyncEnumerable&lt;T&gt;</p><p>Asynchrones Streaming</p><p>CreateQuery&lt;T&gt;()</p><p>IEsqlQueryable&lt;T&gt;</p><p>Erweiterte Zusammensetzung und Inspektion</p><p>SubmitAsyncQueryAsync&lt;T&gt;(...)</p><p>EsqlAsyncQuery&lt;T&gt;</p><p>Langlaufende serverseitige Abfragen</p><p>Eine vollständige Feature-Referenz – einschließlich Abfrageoptionen, Zugriff auf mehrere Felder, verschachtelter Objekte und der Verarbeitung mehrwertiger Felder – finden Sie in der <a href="https://www.elastic.co/docs/reference/elasticsearch/clients/dotnet/linq-to-esql">LINQ to ES|QL-Dokumentation</a>.</p><h2>Fazit</h2><p>LINQ to ES|QL bringt die volle Ausdruckskraft von C# LINQ in die ES|QL-Abfragesprache von Elasticsearch, sodass Sie stark typisierte, kombinierbare Abfragen schreiben können, ohne Abfragezeichenfolgen von Hand erstellen zu müssen. Mit automatischer Parametererfassung, Streaming-Materialisierung und einer geschichteten Paketarchitektur, die von eigenständiger Übersetzung zum vollständigen Elasticsearch-Client skaliert, fügt es sich natürlich in .NET-Anwendungen jeder Größe ein. Installieren Sie den neuesten Client, verweisen Sie Ihre LINQ-Ausdrücke auf einen Index und überlassen Sie den Rest dem Provider.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/linq-esql-c-elasticsearch-net-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/linq-esql-c-elasticsearch-net-client</guid>
    <category><![CDATA[ES|QL]]></category>
    <category><![CDATA[Vektordatenbank]]></category>
    <dc:creator><![CDATA[Florian Bernd,Martijn Laarman]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfa35fbcbbf4959f/6a1705b9dc55de19a4e00d07/e54132e915217063e9ed0ec45059c6cfc38e31dd-1280x720.png" length="0" type="image/png"/>
    <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Schnellere ES|QL-Statistiken mit Hashtabellen im Schweizer Stil]]></title>
    <description><![CDATA[Wie von der Schweiz inspiriertes Hashing und ein SIMD-freundlicher Entwurf konsistente, messbare Geschwindigkeitssteigerungen in der Elasticsearch-Abfragesprache (ES|QL) liefern.]]></description>
    <content:encoded><![CDATA[<p>Wir haben kürzlich zentrale Teile der Hashtabellenimplementierung von Elasticsearch durch einen Entwurf im Schweizer Stil ersetzt und bis zu 2–3-mal schnellere Build- und Iterationszeiten bei einheitlichen, hochkardinalen Workloads beobachtet. Das Ergebnis ist eine geringere Latenz, ein besserer Durchsatz und eine vorhersehbarere Leistung für die Elasticsearch-Abfragesprache (ES|QL) sowie Statistik- und Analyseoperationen.</p><h2>Warum das wichtig ist</h2><p>Die meisten typischen analytischen Workflows laufen letztendlich auf die Gruppierung von Daten hinaus. Ob es nun um die Berechnung der durchschnittlichen Bytes pro Host, das Zählen von Ereignissen pro Nutzer oder das Aggregieren von Metriken über Dimensionen hinweg geht, die Kernoperation ist immer dieselbe – Schlüssel werden Gruppen zugeordnet und laufende Aggregate aktualisiert.</p><p>In kleinem Maßstab funktioniert fast jede vernünftige Hashtabelle einwandfrei. Bei großer Skalierung (Hunderte Millionen Dokumente und Millionen verschiedener Gruppen) beginnen Details eine Rolle zu spielen. Auslastungsfaktoren, Sondierungsstrategie, Speicherlayout und Cache-Verhalten können den Unterschied zwischen linearer Leistung und einer Flut von Cache-Fehlern ausmachen.</p><p>Elasticsearch unterstützt diese Workloads seit Jahren und wir suchen stets nach Möglichkeiten, die Kernalgorithmen zu modernisieren. Daher haben wir einen neueren, von Schweizer Tabellen inspirierten Ansatz evaluiert und ihn auf die Art und Weise angewendet, wie ES|QL Statistiken berechnet.</p><h2>Was genau sind Schweizer Tabellen?</h2><p>Schweizer Tabellen sind eine Familie moderner Hash-Tabellen, die von Googles SwissTable popularisiert und später in Abseil und anderen Bibliotheken übernommen wurden.</p><p>Traditionelle Hash-Tabellen verbringen viel Zeit damit, Zeiger zu verfolgen oder Schlüssel zu laden, nur um festzustellen, dass sie nicht übereinstimmen. Das definierende Feature von Schweizer Tabellen ist die Fähigkeit, die meisten Anfragen mit einer winzigen, im Cache befindlichen Array-Struktur abzulehnen, die getrennt von Schlüsseln und Werten gespeichert wird und als <em>Kontrollbytes</em> bezeichnet wird, um den Speicherverkehr drastisch zu reduzieren.</p><p>Jedes Kontrollbyte repräsentiert einen einzelnen Slot und kodiert in unserem Fall zwei Dinge: ob der Slot leer ist und einen kurzen Fingerabdruck, der aus dem Hash abgeleitet wird. Diese Steuerbytes sind zusammenhängend im Speicher angeordnet, typischerweise in Gruppen von 16, was sie ideal für die SIMD-Verarbeitung <a href="https://en.wikipedia.org/wiki/Single_instruction,_multiple_data">(Single Instruction, Multiple Data)</a>.</p><p>Anstatt einen Slot nach dem anderen zu testen, scannen Schweizer Tabellen einen gesamten Kontrollbyte-Block mithilfe von Vektorinstruktionen. In einer einzigen Operation vergleicht die CPU den Fingerabdruck des eingehenden Schlüssels mit 16 Slots und filtert leere Einträge heraus. Nur bei den wenigen Kandidaten, die diesen Schnelltest überstehen, ist das Laden und Vergleichen der tatsächlichen Schlüssel erforderlich.</p><p>Dieses Design tauscht eine kleine Menge zusätzlicher Metadaten gegen eine viel bessere Cache-Lokalität und weitaus weniger zufällige Ladevorgänge ein. Wenn die Tabelle wächst und die Sondenketten länger werden, werden diese Eigenschaften immer wertvoller.</p><h2>SIMD im Mittelpunkt</h2><p>Der eigentliche Star der Show ist SIMD.</p><p>Die Steuerbytes sind nicht nur kompakt, sondern auch explizit für die Verarbeitung mit Vektorbefehlen konzipiert. Ein einzelner SIMD-Vergleich kann 16 Fingerabdrücke gleichzeitig überprüfen und verwandelt, was normalerweise eine Schleife wäre, in eine Handvoll breiter Operationen. Zum Beispiel:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1f710e87dd749ab3/6a170cc46234e052dadb1a49/bd418778f0c6144f8f5f18419f6220ac0c935c7a-903x407.png" alt="SIMD im Zentrum von Elasticsearch" /><p>In der Praxis bedeutet das:</p><ul><li><p>Weniger Zweige.</p></li><li><p>Kürzere Testketten.</p></li><li><p>Weniger Ladevorgänge aus Schlüssel- und Wertspeicher.</p></li><li><p>Viel bessere Nutzung der Ausführungseinheiten der CPU.</p></li></ul><p>Die meisten Suchvorgänge kommen nie über den Control-Byte-Scan hinaus. Wenn sie das tun, ist die verbleibende Arbeit zielgerichtet und vorhersehbar. Das ist genau die Art von Arbeitslast, für die moderne CPUs gut geeignet sind.</p><h2>SIMD unter der Haube</h2><p>Für Leser, die gerne einen Blick hinter die Kulissen werfen, hier eine Erklärung, was beim Einfügen eines neuen Schlüssels in die Tabelle passiert. Wir verwenden die Panama Vector API mit 128-Bit-Vektoren und bearbeiten somit 16 Kontrollbytes parallel.</p><p>Der folgende Ausschnitt zeigt den Code, der auf einem Intel Rocket Lake mit AVX-512 generiert wurde. Obwohl die Anweisungen diese Umgebung widerspiegeln, hängt das Design nicht von AVX-512 ab. Die gleichen hochstufigen Vektoroperationen werden auf anderen Plattformen mit gleichwertigen Befehlen (zum Beispiel AVX2, SSE oder NEON) ausgesendet.</p>; Load 16 control bytes from the control block
vmovdqu xmm0, XMMWORD PTR [r9+r10*1+0x10]

; Broadcast the 7-bit fingerprint of the new key across the vector
vpbroadcastb xmm1, r11d

; Compare all 16 control bytes to the new fingerprint
vpcmpeqb k7, xmm0, xmm1
kmovq rbx, k7

; Check if any matches were found
test rbx, rbx
jne &lt;handle_match&gt;<p>Jede Anweisung hat eine klare Rolle im Einfügeprozess:</p><ul><li><p><code>vmovdqu</code>: Lädt 16 aufeinanderfolgende Steuerbytes in das 128-Bit-<code>xmm0</code>-Register.</p></li><li><p><code>vpbroadcastb</code>: Repliziert den 7-Bit-Fingerabdruck des neuen Schlüssels über alle Spuren des <code>xmm1</code>-Registers.</p></li><li><p><code>vpcmpeqb</code>: Vergleicht jedes Steuerbyte mit dem gesendeten Fingerabdruck und erstellt eine Maske mit möglichen Übereinstimmungen.</p></li><li><p><code>kmovq</code> + <code>test</code>: Verschiebt die Maske in ein allgemeines Register und überprüft schnell, ob ein Match existiert.</p></li></ul><p>Schließlich entschieden wir uns dafür, Gruppen von jeweils 16 Kontrollbytes zu untersuchen, da Benchmarks zeigten, dass eine Erweiterung auf 32 oder 64 Bytes mit breiteren Registern keinen messbaren Leistungsvorteil brachte.</p><h2>Integration in ES|QL</h2><p>Die Einführung des Hashing im Schweizer Stil in Elasticsearch war nicht einfach ein direkter Ersatz. ES|QL stellt hohe Anforderungen an die Speicherverwaltung, die Sicherheit und die Integration mit dem Rest der Compute Engine.</p><p>Wir haben die neue Hash-Tabelle eng in die Speicherverwaltung von Elasticsearch integriert, einschließlich des Seitenrecyclers und der Abrechnung von Schutzschaltern, um sicherzustellen, dass die Zuweisungen sichtbar und begrenzt bleiben. Die Aggregationen von Elasticsearch werden dicht gespeichert und durch eine Gruppen-ID indexiert, wodurch das Speicherlayout kompakt und schnell für Iterationen bleibt und zudem bestimmte Leistungsoptimierungen durch zufälligen Zugriff ermöglicht werden.</p><p>Bei Byte-Schlüsseln mit variabler Länge wird der vollständige Hash zusammen mit der Gruppen-ID zwischengespeichert. Dadurch wird die Neuberechnung teurer Hash-Codes während der Sondierung vermieden und die Cache-Lokalität verbessert, indem zusammengehörige Metadaten nahe beieinander gehalten werden. Während des Rehashings können wir uns auf den zwischengespeicherten Hash und die Kontroll-Bytes verlassen, ohne die Werte selbst zu inspizieren, wodurch die Kosten für die Größenänderung niedrig gehalten werden.</p><p>Eine wichtige Vereinfachung in unserer Implementierung besteht darin, dass Einträge niemals gelöscht werden. Dadurch werden <em>Tombstones</em> (Markierungen zur Identifizierung zuvor belegter Steckplätze) überflüssig, und leere Steckplätze bleiben wirklich leer, was das Verhalten der Sonde weiter verbessert und Kontroll-Byte-Scans effizient macht.</p><p>Das Ergebnis ist ein Design, das sich nahtlos in das Ausführungsmodell von Elasticsearch einfügt und gleichzeitig die Leistungsmerkmale beibehält, die Schweizer Tabellen so attraktiv machen.</p><h2>Wie ist die Performance?</h2><p>Bei kleinen Kardinalitäten schneiden die Schweizer Tabellen in etwa gleich gut ab wie die bestehende Implementierung. Das ist zu erwarten: Bei kleinen Tabellen spielen Cache-Effekte eine geringere Rolle und es gibt wenig Optimierungsbedarf.</p><p>Mit zunehmender Kardinalität ändert sich das Bild schnell.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09b13af2fe162f59/6a170cc66f7f04485c9148b8/24900afc47ab07b0e9933f6117b99d0f4613f794-962x599.png" alt="ES|QL-Statistiken mit Hashtabellen im Schweizer Stil" /><p>Die obige Heatmap zeigt die Zeitverbesserungsfaktoren für verschiedene Schlüsselgrößen (8, 32, 64 und 128 Byte) über Kardinalitäten von 1.000 bis 10.000.000 Gruppen hinweg. Mit zunehmender Kardinalität steigt der Verbesserungsfaktor stetig an und erreicht bei Gleichverteilungen Werte von bis zu 2–3x.</p><p>Dieser Trend entspricht genau dem, was die Konstruktion vorhersagt. Höhere Kardinalität führt zu längeren Prüfketten in traditionellen Hash-Tabellen, während die meisten Suchvorgänge nach wie vor in SIMD-freundlichen Kontroll-Byte-Blöcken gelöst werden.</p><h2>Das Cache-Verhalten erzählt die Geschichte</h2><p>Um die Beschleunigungen besser zu verstehen, haben wir denselben JMH-<a href="https://github.com/elastic/elasticsearch/pull/139343/files#diff-d0e0cc91a7495bf36b2d44eacce95f5185d01879e5f6c38089ac7a89aad17da7"><code>benchmarks</code></a> unter Linux <code>perf</code> ausgeführt und Cache- sowie TLB-Statistiken erfasst.</p><p>Im Vergleich zur ursprünglichen Implementierung benötigt die Schweizer Version insgesamt etwa 60 % weniger Cache-Zugriffe. Die Last-Level-Cache-Ladevorgänge sinken um mehr als das Vierfache, und LLC-Ladefehler gehen um mehr als das Sechsfache zurück. Da LLC-Fehlzugriffe oft direkt in Hauptspeicherzugriffe übersetzt werden, erklärt diese Reduzierung allein einen großen Teil der End-to-End-Verbesserung.</p><p>Näher an der CPU beobachten wir weniger L1-Datencache-Fehler und fast 6x weniger TLB-Datenfehler, was auf eine engere räumliche Lokalität und besser vorhersagbare Speicherzugriffsmuster hindeutet.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb987a5bd98c0d7eb/6a170cc8a929cf9655ae0a25/6e49b7609fba83e33692cb9834552b6ca7e42a83-998x499.png" alt="Cache-Verhalten: Original vs. ES|QL-Statistiken mit Hash-Tabellen im Schweizer Stil" /><p>Dies ist der praktische Nutzen von SIMD-freundlichen Kontrollbytes. Anstatt Schlüssel und Werte immer wieder von verstreuten Speicherplätzen zu laden, werden die meisten Suchvorgänge durch das Durchsuchen einer kompakten, im Cache befindlichen Struktur gelöst. Weniger berührter Speicher bedeutet weniger Fehltritte, und weniger Fehltritte bedeuten schnellere Abfragen.</p><h2>Fazit</h2><p>Indem wir einen Hashtabellenentwurf im Schweizer Stil verwendeten und uns stark auf SIMD-freundliche Sondierungen konzentrierten, erreichten wir 2–3-fache Beschleunigungen für ES|QL-Statistik-Workloads mit hoher Kardinalität sowie eine stabilere und vorhersehbarere Leistung.</p><p>Diese Arbeit zeigt, wie moderne CPU-fähige Datenstrukturen erhebliche Verbesserungen ermöglichen können, selbst bei bekannten Problemen wie Hash-Tabellen. Hier gibt es mehr Raum für Erkundungen, wie etwa zusätzliche Spezialisierungen von primitiven Typen und die Verwendung in anderen Pfaden mit hoher Kardinalität, wie Joins, die alle Teil der umfassenderen und fortlaufenden Bemühungen sind, die internen Abläufe von Elasticsearch kontinuierlich zu modernisieren.</p><p>Wenn Sie an den Details interessiert sind oder die Arbeit verfolgen möchten, schauen Sie sich diesen <a href="https://github.com/elastic/elasticsearch/pull/139343">Pull Request</a> und den <a href="https://github.com/elastic/elasticsearch/issues/138799">Meta-Issue</a>-Fortschritt auf Github an.</p><p>Viel Spaß beim Hashing!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/esql-swiss-hash-stats</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/esql-swiss-hash-stats</guid>
    <category><![CDATA[ES|QL]]></category>
    <dc:creator><![CDATA[Chris Hegarty,Matthew Alp,Nik Everett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf76dd688c5b737e6/6a170cc9839dfa7fc7dcff40/21036e031070f14faccb2b53b22723de2750c391-1280x720.png" length="0" type="image/png"/>
    <pubDate>Mon, 19 Jan 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Einführung der Elasticsearch-Unterstützung in der Google MCP Toolbox for Databases]]></title>
    <description><![CDATA[Erfahren Sie, wie die Unterstützung für Elasticsearch jetzt in der Google MCP Toolbox for Databases verfügbar ist, und nutzen Sie ES|QL-Tools, um Ihren Index sicher mit jedem MCP-Client zu integrieren.]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel zeigen wir Ihnen, wie Sie die Google MCP Toolbox mit <a href="https://github.com/elastic/elasticsearch">Elasticsearch</a> nutzen, um ein einfaches Tool zur Extraktion von Informationen aus einem Elasticsearch-Index zu erstellen.</p><p>Wir haben vor Kurzem zum Open-Source-Projekt <a href="https://github.com/googleapis/genai-toolbox">Google MCP Toolbox for Databases</a> beigetragen, indem wir Unterstützung für Elasticsearch als Datenbank hinzugefügt haben.</p><p>Mit diesem neuen Feature können Sie jetzt die Google MCP Toolbox verwenden, um eine Verbindung zu Elasticsearch herzustellen und direkt mit Ihren Daten zu „kommunizieren“.</p><h2>Elasticsearch</h2><p>Wir benötigen eine laufende Elasticsearch-Instanz. Sie können eine kostenlose Testversion auf <a href="https://www.elastic.co/cloud">Elastic Cloud</a> aktivieren oder es lokal mit dem <a href="https://github.com/elastic/start-local">start-local-Skript</a> installieren:</p>curl -fsSL https://elastic.co/start-local | sh<p>Dadurch werden Elasticsearch und Kibana auf Ihrem Computer installiert und ein API-Schlüssel generiert, der zur Konfiguration der Google MCP Toolbox verwendet wird.</p><p>Der API-Schlüssel wird als Ausgabe des vorherigen Befehls angezeigt und in einer .env-Datei im Ordner elastic-start-local gespeichert.</p><h2>Installieren Sie den Beispieldatensatz</h2><p>Nach der Installation können Sie sich mit dem Benutzernamen <em>elastic</em> und dem vom start-local-Skript generierten Passwort (gespeichert in einer .env-Datei) bei Kibana anmelden.</p><p>Sie können den Datensatz für <strong>E-Commerce-Bestellungen </strong>, der von Kibana verfügbar ist, installieren. Sie enthält einen einzigen Index namens <strong>kibana_sample_data_ecommerce</strong>, der Informationen über 4.675 Bestellungen von einer E-Commerce-Website enthält. Für jede Bestellung haben wir folgende Informationen:</p><ul><li><p>Kundeninformationen (Name, Ausweis, Geburtsdatum, E-Mail-Adresse usw.)</p></li><li><p>Bestelldatum</p></li><li><p>Bestell-ID</p></li><li><p>Produkte (Liste aller Produkte mit Preis, Menge, ID, Kategorie, Rabatt usw.)</p></li><li><p>SKU</p></li><li><p>Gesamtpreis (ohne Steuern, mit Steuern)</p></li><li><p>Gesamtmenge</p></li><li><p>Geoinformationen (Stadt, Land, Kontinent, Ort, Region)</p></li></ul><p>Um die Beispieldaten zu installieren, öffnen Sie die Seite <strong>Integrationen</strong> in Kibana (suchen Sie in der Suchleiste oben nach „Integration“) und installieren Sie die „Beispieldaten“. Weitere Details finden Sie in der Dokumentation hier: <a href="https://www.elastic.co/docs/explore-analyze/#gs-get-data-into-kibana">https://www.elastic.co/docs/explore-analyze/#gs-get-data-into-kibana</a>.</p><p>Ziel dieses Artikels ist es, zu zeigen, wie einfach es ist, die Google MCP Toolbox so zu konfigurieren, dass sie sich mit Elasticsearch verbindet und mit dem <strong>kibana_sample_data_ecommerce-Index</strong> in natürlicher Sprache interagiert.</p><h2>Google MCP Toolbox</h2><p>Die Google MCP Toolbox ist ein Open-Source-MCP-Server, der entwickelt wurde, um Anwendungen und KI-Agenten die sichere und effiziente Interaktion mit Datenbanken zu erleichtern. Das Projekt, das zuvor unter dem Namen „GenAI Toolbox for Databases“ bekannt war, wurde nach der vollständigen Kompatibilität mit dem <a href="https://www.anthropic.com/news/model-context-protocol">Model Context Protocol</a> (MCP) umbenannt. Ziel ist es, den üblicherweise beim Verbinden von Agenten mit Datenbanken erforderlichen hohen Aufwand zu reduzieren, indem Verbindungspooling, Authentifizierung, Beobachtbarkeit und andere betriebliche Belange im Hintergrund übernommen werden.</p><p>Im Kern ermöglicht es die Toolbox Entwicklern, wiederverwendbare, hochwertige Werkzeuge zu definieren, die Datenbankinteraktionen kapseln. Diese Tools können dann von jedem MCP-kompatiblen Client – wie beispielsweise einem KI-Agenten – aufgerufen werden, ohne dass der Client Low-Level-SQL-Abfragen implementieren oder Datenbankverbindungen verwalten muss. Dieser Ansatz reduziert die Menge an Boilerplate-Code, die für den Aufbau datenbankbewusster Agenten benötigt wird, drastisch und ermöglicht die Integration fortgeschrittener Datenoperationen in nur wenigen Anwendungszeilen. Sobald ein Werkzeug definiert ist, kann es von mehreren Agenten, Frameworks oder Sprachen gemeinsam genutzt werden (Abbildung 1).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte90070297ee83546/6a16fa29964cea694b08b972/137cea290bb70ad5da21853f9a6358cef4cf7451-1248x1056.png" alt="" /><p>Ein großer Vorteil der Nutzung der Toolbox ist das integrierte Sicherheitsmodell. Authentifizierungsabläufe wie OAuth2 und OIDC werden nativ unterstützt, sodass Entwickler:innen die Verarbeitung oder Speicherung sensibler Datenbankzugangsdaten in Agenten vermeiden können. Die Plattform bietet außerdem Beobachtbarkeit-Features – einschließlich Metriken und Tracing – über OpenTelemetry, was für Debugging, Monitoring und Deployments in der Produktionsumgebung unerlässlich ist. Insgesamt dient die MCP Toolbox als einheitliche, sichere und erweiterbare Schnittstelle zur Interaktion mit Ihren Daten von jedem MCP-fähigen System.</p><h2>So installieren Sie die MCP Toolbox</h2><p>Sie können den MCP-Toolbox-Server unter Linux mit folgendem Befehl installieren:</p>export VERSION=0.21.0
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
chmod +x toolbox<p>Für eine Installation unter macOS oder Windows können Sie den <a href="https://googleapis.github.io/genai-toolbox/getting-started/introduction/#installing-the-server">hier</a> beschriebenen Anweisungen folgen.</p><h2>Toolbox für Elasticsearch konfigurieren</h2><p>Um die MCP Toolbox für Elasticsearch zu konfigurieren, müssen wir eine <strong>tools.yaml</strong>-Datei erstellen, und zwar wie folgt:</p>sources:
  my-cluster:
    kind: elasticsearch
    addresses:
      - http://localhost:9200
    apikey: &lt;insert-here-api-key&gt;

tools:
  customer-orders:
    kind: elasticsearch-esql
    source: my-cluster
    description: Get the orders made by a customer identified by name.
    query: |
    	FROM kibana_sample_data_ecommerce | WHERE MATCH(customer_full_name, ?name, {"operator": "AND"})
    parameters:
      - name: name
        type: string
        description: The customer name.

toolsets:
  elasticsearch-tools:
    - customer-orders<p>Sie müssen den Wert <strong>&lt;insert-here-api-key&gt;</strong> durch einen gültigen Elasticsearch-API-Schlüssel ersetzen. Wenn Sie Elasticsearch lokal mit start-local ausführen, finden Sie den API-Schlüssel in der von start-local generierten .env-Datei unter der Variable <strong>ES_LOCAL_API_KEY</strong>. Wenn Sie Elastic Cloud verwenden, können Sie einen API-Schlüssel generieren, indem Sie das <a href="https://www.elastic.co/docs/deploy-manage/api-keys/elastic-cloud-api-keys">hier</a> beschriebene Verfahren befolgen.</p><p>Die vorherigen Tools enthalten die folgende ES|QL-Abfrage für Elasticsearch:</p><p>Falls Ihnen ES|QL nicht geläufig ist: Es handelt sich um eine von Elastic entwickelte Abfragesprache, die ähnlich wie SQL funktioniert und mit der man einen oder mehrere Indizes durchsuchen kann. Mehr über ES|QL finden Sie in der offiziellen Dokumentation <a href="https://www.elastic.co/docs/reference/query-languages/esql">hier</a>.</p><p>Die obige Abfrage sucht nach allen im <strong>kibana_sample_data_ecommerce-Index</strong> gespeicherten Bestellungen, die den Namen des:der angegebenen Kund:in enthalten, und verwendet den <strong>?name-Parameter</strong> (das Fragezeichen bezeichnet einen Parameter).</p><p>Der Name des Kunden wird in der vorherigen YAML-Konfiguration mit dem Typ „Zeichenfolge“ und der Beschreibung „Der Name des Kunden“ definiert.</p><p>Mit diesem Tool können Fragen zu den Bestellungen eines:einer Kund:in beantwortet werden – zum Beispiel: <em>Wie viele Bestellungen hat Kund:in Foo im Oktober 2025 aufgegeben?</em></p><p>Die Beschreibungen der Werkzeuge und ihrer Parameter sind unerlässlich, um die relevanten Informationen aus der natürlichsprachlichen Anfrage des:der Nutzer:in zu extrahieren. Diese Extraktion erfolgt mithilfe der <strong>Funktionsaufruf-Funktion</strong> eines Large Language Models (LLM). In der Praxis kann ein LLM bestimmen, welche Funktion (welches Werkzeug) ausgeführt werden muss, um die notwendigen Informationen zu erhalten, sowie die entsprechenden Parameter für diese Funktion.</p><p>Für weitere Informationen zu Funktionsaufrufen empfehlen wir, den Artikel <a href="https://www.elastic.co/search-labs/blog/function-calling-with-elastic">OpenAI Function Calling with Elasticsearch</a> von Ashish Tiwari zu lesen.</p><h2>Führen Sie den Toolbox-Server aus</h2><p>Sie können die MCP Toolbox unter Verwendung der vorherigen tools.yaml-Datei mit folgendem Befehl ausführen:</p>./toolbox --tools-file tools.yaml --ui<p>Der Parameter<strong> –ui</strong> führt eine Webanwendung unter <a href="http://127.0.0.1:5000/ui">http://127.0.0.1:5000/ui</a> aus (Abbildung 2).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0fb3953fae603572/6a16fa2aa6c2b92763e794fb/3caf2339b632bafd5847af1ed8b33b518a25b8a2-1600x314.png" alt="" /><p>Sie können die Option <strong>Tools</strong> &gt; <strong>customer-orders</strong> auswählen und im Feld <strong>Parametername</strong> einen Kundennamen eingeben (z. B. Gwen Sanders) und anschließend auf die Schaltfläche <strong>Tool ausführen</strong> klicken. Sie sollten eine JSON-Reaktion sehen, wie in Abbildung 3 dargestellt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca02df8c78cb39ff/6a16fa2c961e6909b5c4cd22/b167e0142afb8919d9cedf6d0fa431d33d0e55f8-1600x933.png" alt="" /><p>Die Einrichtung ist abgeschlossen, und die MCP Toolbox kann das Tool <strong>customer-orders</strong> ausführen, um mit Elasticsearch zu kommunizieren und dabei die ES|QL-Anfrage auszuführen.</p><h2>Verwendung der MCP Toolbox mit Gemini CLI</h2><p>Wir können jeden beliebigen MCP-Client verwenden, um mit der MCP Toolbox für Datenbanken zu kommunizieren. Zum Beispiel können wir <a href="https://github.com/google-gemini/gemini-cli">Gemini CLI</a> verwenden, ein Befehlszeilen-Tool zur Nutzung von Gemini. Sie können die Gemini CLI gemäß den <a href="https://geminicli.com/docs/get-started/installation/">hier</a> beschriebenen Anweisungen installieren.</p><p>Gemini CLI bietet eine vorkonfigurierte Erweiterung für die MCP Toolbox an, verfügbar unter <a href="https://github.com/gemini-cli-extensions/mcp-toolbox">gemini-cli-extensions/mcp-toolbox</a>. Sie können diese Erweiterung installieren, indem Sie folgenden Befehl ausführen:</p>gemini extensions install https://github.com/gemini-cli-extensions/mcp-toolbox<p>Nach der Installation müssen Sie in das Verzeichnis gehen, in dem Sie die Konfigurationsdatei tools.yaml für die MCP Toolbox gespeichert haben, und Gemini CLI wie folgt ausführen (dieser Schritt ist erforderlich, damit die Gemini-CLI automatisch mit der MCP-Toolbox konfiguriert wird):</p>gemini<p>In Abbildung 4 sollten Sie eine Ausgabeanzeige sehen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7245c10b9e32cd6/6a16fa2d964cea073208b976/0f22df6d3da13c1dc50dcb560414fa7c630eb9a7-1434x341.png" alt="" /><p>Mit dem folgenden Befehl können Sie überprüfen, ob die MCP Toolbox verbunden ist:</p>/mcp list<p>Sie sollten die <strong>mcp_toolbox</strong> mit den aufgelisteten Tools<strong> customer-orders</strong> sehen (Abbildung 5).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte857b42dbe604203/6a16fa2f8b73cb531b189e33/97edbc40de9e44f469f6f3a09427532be167de0e-493x155.png" alt="" /><p>Wenn die MCP Toolbox mit der Gemini CLI verbunden ist, können wir nun versuchen, einige Fragen zu stellen, wie zum Beispiel: „ <em>Gib mir die Bestellungen für die Kundin Gwen Sanders</em>.“ Anschließend fordert die Gemini CLI die Berechtigung an, das Tool customer-orders vom Server mcp_toolbox auszuführen (siehe Abbildung 6).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfb7ea752c1a39da7/6a16fa30cdacbfdf937d27ff/c052f3b5e49436903b804280c0065f67ee02444b-1432x284.png" alt="" /><p>Nach der Bestätigung führt Gemini CLI die Anfrage an die MCP Toolbox aus und erhält als Ergebnis eine JSON-Reaktion, die zur Formatierung der Reaktion verwendet wird (Abbildung 7).</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb9f6e04987137a9f/6a16fa320811ae2297e9fef7/7ea5128f1705951c2757af6da4b456d394d4a080-1432x734.png" alt="" /><p>Die Reaktion von Gemini CLI wird berichten, dass Gwen Sanders lediglich eine Bestellung über zwei Produkte zum Gesamtpreis von 132 Euro aufgegeben hat.</p><h2>MCP Toolbox SDKs</h2><p>Die Google MCP Toolbox bietet außerdem ein SDK an, um alle Funktionen eines in Go, Python und Javascript geschriebenen Programms abzurufen.</p><p>Das Python SDK ist beispielsweise auf GitHub unter folgender Seite verfügbar: <a href="https://github.com/googleapis/mcp-toolbox-sdk-python">https://github.com/googleapis/mcp-toolbox-sdk-python</a>.</p><p>Wir müssen einen einfachen Agenten erstellen, der mit der MCP Toolbox verbunden werden kann. Wir müssen die folgenden Pakete installieren:</p>pip install toolbox-core
pip install google-adk<p>Und erstellen Sie ein neues Agentenprojekt mit folgendem Befehl:</p>adk create my_agent<p>Dadurch wird ein neues Verzeichnis namens <strong>my_agent</strong> mit einer Datei <strong>agent.py</strong> erstellt.</p><p>Aktualisieren Sie <strong>my_agent/agent.py</strong> mit dem folgenden Inhalt, um eine Verbindung zu Toolbox herzustellen:</p>from google.adk import Agent
from google.adk.apps import App
from toolbox_core import ToolboxSyncClient

client = ToolboxSyncClient("http://127.0.0.1:5000")

root_agent = Agent(
    name='root_agent',
    model='gemini-2.5-flash',
    instruction="You are a helpful AI assistant designed to search information about a dataset of ecommerce orders.",
    tools=client.load_toolset(),
)

app = App(root_agent=root_agent, name="my_agent")<p>Erstellen Sie eine <strong>.env</strong>-Datei mit Ihrem Google API-Schlüssel: </p>echo 'GOOGLE_API_KEY="YOUR_API_KEY"' &gt; my_agent/.env<p>Schließlich können wir den Agenten ausführen und die Ergebnisse beobachten. Um den Agenten auszuführen, können Sie folgenden Befehl ausführen:</p>adk run my_agent<p>Alternativ können Sie ihn über eine Webschnittstelle bereitstellen:</p>adk web --port 8000<p>In beiden Tickets können Sie mit der MCP Toolbox über eine Q&amp;A-Schnittstelle interagieren. Sie können zum Beispiel die vorherige Frage stellen: <em>Geben Sie mir die Bestellungen der Kundin Gwen Sanders</em>.</p><p>Weitere Informationen zu den verschiedenen SDKs finden Sie auf <a href="https://googleapis.github.io/genai-toolbox/sdks/">dieser Dokumentationsseite</a>.</p><h2>Fazit</h2><p>In diesem Artikel haben wir die Elasticsearch-Integration für die Google MCP Toolbox for Databases demonstriert. Mithilfe einer einfachen YAML-Konfigurationsdatei können wir eine Reihe von Tools definieren, die Fragen in natürlicher Sprache mithilfe der ES|QL-Sprache in Elasticsearch-Abfragen übersetzen.</p><p>Wir haben gezeigt, wie man mit dem Datensatz kibana_sample_data_ecommerce interagiert, der Bestellungen von einer Website enthält. Mit dieser Konfigurationsdatei können wir den MCP Toolbox-Server einfach ausführen und uns von jedem MCP-Client aus mit ihm verbinden.</p><p>Abschließend haben wir gezeigt, wie man die Gemini-CLI als Client nutzt, um sich mit der MCP Toolbox for Databases zu verbinden und die in Elasticsearch gespeicherten E-Commerce-Daten abzufragen. Wir haben eine Abfrage in natürlicher Sprache ausgeführt, um Informationen über Bestellungen für eine:n bestimmte:n, namentlich identifizierte:n Kund:in abzurufen.</p><p>Während das MCP-Ökosystem weiter wächst, schafft dieses Muster – leichte Werkzeugdefinitionen mit sicherer, produktionsreifer Infrastruktur – neue Möglichkeiten, immer leistungsfähigere, datenbewusste Agenten mit minimalem Aufwand zu entwickeln. Ob Sie nun lokal mit den Elastic-Beispieldatensätzen experimentieren oder Suchfunktionen in eine größere Anwendung integrieren, die MCP Toolbox bietet eine zuverlässige, erweiterbare Grundlage für die Interaktion mit Ihren Elasticsearch-Daten unter Verwendung natürlicher Sprache.</p><p>Weitere Informationen zur Entwicklung agentischer KI-Anwendungen finden Sie im Artikel <a href="https://search-labs-redesign.vercel.app/search-labs/blog/ai-agentic-workflows-elastic-ai-agent-builder">Building AI Agentic Workflows with Elasticsearch</a> von Anish Mathur und Dana Juratoni.</p><p>Weitere Informationen über die Google MCP Toolbox finden Sie unter <a href="https://googleapis.github.io/genai-toolbox/getting-started/introduction/">https://googleapis.github.io/genai-toolbox/getting-started/introduction/.</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/google-mcp-toolbox-elasticsearch-support</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/google-mcp-toolbox-elasticsearch-support</guid>
    <category><![CDATA[ES|QL]]></category>
    <category><![CDATA[Agentische KI]]></category>
    <dc:creator><![CDATA[Enrico Zimuel,Laurent Saint-Félix]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72d49893c51407cf/6a16fa33cf4f2502bab2cf7e/425a48691f436ed47c9bdfaf5d561ac122b2c472-1062x668.png" length="0" type="image/png"/>
    <pubDate>Fri, 12 Dec 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[ES|QL in 9.2: Unterstützung für intelligente Lookup Joins und Zeitreihen]]></title>
    <description><![CDATA[Entdecken Sie drei separate Updates für ES|QL in Elasticsearch 9.2: ein verbessertes LOOKUP JOIN für ausdrucksstärkere Datenkorrelation, den neuen TS-Befehl für die Zeitreihenanalyse und den flexiblen INLINE STATS-Befehl für die Aggregation.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch 9.2, das im Oktober veröffentlicht wurde, bietet zahlreiche bedeutende Verbesserungen, die die Analyse Ihrer Daten schneller, flexibler und zugänglicher als je zuvor machen. Im Mittelpunkt dieser Version stehen wichtige Verbesserungen an ES|QL, unserer Pipe-Abfragesprache, die entwickelt wurden, um Endnutzer:innen direkt noch mehr Nutzen zu bieten.</p><p>Hier ist ein Überblick über die Features in Elasticsearch 9.2, die Ihre Datenanalyse-Workflows mit ES|QL verändern werden.</p><h2>Revolutionierung der Datenkorrelation: Eine intelligentere, schnellere und flexiblere Lookup-Verknüpfung</h2><p>Der Befehl <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/lookup-join">LOOKUP JOIN</a> in ES|QL hat in Elasticsearch 9.2 eine bedeutende Transformation durchlaufen und ist deutlich effizienter und vielseitiger geworden. LOOKUP JOIN kombiniert Daten aus Ihrer ES|QL-Abfrageergebnistabelle mit übereinstimmenden Einträgen aus einem angegebenen Lookup-Modus-Index. Es fügt Felder aus dem Lookup-Index als neue Spalten zu Ihrer Ergebnistabelle hinzu, basierend auf übereinstimmenden Werten im Join-Feld. Zuvor war die Verknüpfung von Daten auf ein einziges Feld und einfache Gleichheit beschränkt. Das ist Geschichte! Dank dieser Erweiterungen können Sie komplexe Datenkorrelationsszenarien mühelos bewältigen.</p><p><strong>Zu den wichtigsten Verbesserungen von Lookup Join gehören:</strong></p><ul><li><p><strong>Verknüpfungen mit mehreren Feldern:</strong> Einfaches Verknüpfen mehrerer Felder. So verbinden Sie beispielsweise <code>application_logs</code> mit <code>service_registry</code> anhand von <code>service_name</code>, <code>environment</code> und <code>version:</code></p></li></ul>FROM application_logs
| LOOKUP JOIN service_registry ON service_name, environment, version<ul><li><p><strong>Freischalten komplexer Join-Prädikate mit Ausdrücken (technische Vorschau):</strong></p></li></ul><p>Sie sind nicht mehr auf einfache Gleichheit beschränkt. LOOKUP JOIN ermöglicht es Ihnen nun, <strong>mehrere Kriterien</strong> für die Korrelation anzugeben und eine Reihe von <strong>binären Operatoren</strong> einzubeziehen, darunter ==, !=, &lt;, &gt;, &lt;= und &gt;=. Dies bedeutet, dass Sie hochgradig nuancierte Join-Bedingungen erstellen können, die es Ihnen ermöglichen, viel anspruchsvollere Fragen an Ihre Daten zu stellen.</p><p>Beispiel 1: Ermittlung von Anwendungsmetriken mit SLA-Schwellenwert pro Dienst</p>FROM application_metrics
| LOOKUP JOIN sla_thresholds
      ON service_name == sla_service AND response_time &gt; sla_response_time<p>Beispiel 2: Diese Abfrage berechnet den fälligen Betrag auf Grundlage regionaler Preisrichtlinien, die sich im Laufe der Zeit ändern. Es verknüpft drei Datensätze basierend auf komplexen Datumsbereichs- und Gleichheitsbedingungen, um eine endgültige <code>due_amount</code> zu berechnen. Der zweite Lookup-Join verwendet das Feld <code>measurement_date</code> aus dem Index <code>meter_readings</code> und das Feld <code>region_id</code> aus dem Index <code>customers</code>, um mit dem Index <code>pricing_policies</code> verknüpft zu werden und die richtige Preispolitik für die jeweiligen <code>region</code> und <code>measurement_date</code> zu finden.</p>FROM meter_readings
| LOOKUP JOIN customers
      ON meter_id
| LOOKUP JOIN pricing_policies
      ON
        region_id == region AND
          measurement_date &gt;= policy_begin_date AND
          measurement_date &lt; policy_end_date
| EVAL due_amount = (kwh_consumed * rate_per_kwh + base_charge) * (1 + tax_rate)
| EVAL period = policy_name
| KEEP customer_name, period, due_amount, measurement_date, kwh_consumed,
    rate_per_kwh, base_charge, tax_rate
| SORT measurement_date<ul><li><p><strong>Enorme Leistungsgewinne bei gefilterten Joins: </strong></p></li></ul><p>Wir haben die Leistung für „erweiterte Verknüpfungen” verbessert, die anhand von Lookup-Tabellenbedingungen gefiltert werden. Erweiterte Verknüpfungen führen zu mehreren Übereinstimmungen pro Eingabezeile, wodurch große Zwischenergebnismengen entstehen können. Dies wird noch schlimmer, wenn viele dieser Zeilen durch einen nachfolgenden Filter verworfen werden. In 9.2 optimieren wir diese Verknüpfungen, indem wir unnötige Zeilen herausfiltern, wenn ein Filter auf Suchdaten angewendet wird. Dadurch wird die Verarbeitung von Zeilen vermieden, die verworfen würden. In einigen Szenarien können diese Joins bis zu <strong>1000-mal schneller</strong> sein!</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltce2c948a9a00a348/6a17f1a20b0bed8c08dd368b/002c014ee29b1aaf9ddeb8c554bb76efe3ed180c-1572x954.png" alt="Leistungsgewinne durch gefilterte Joins" /><p>Diese Optimierung ist entscheidend bei der Verarbeitung von „expandierenden Joins“, bei denen eine Suche anfänglich viele potenzielle Übereinstimmungen erzeugen kann. Durch intelligentes Herunterdrücken von Filtern werden nur die relevanten Daten verarbeitet, was die Ausführungszeit von Abfragen drastisch verkürzt und die Echtzeitanalyse großer Datensätze ermöglicht. Das bedeutet, dass Sie Ihre Einblicke viel schneller erhalten, selbst bei sehr großen oder komplexen Join-Operationen.</p><p><strong>Kompatibilität mit der clusterübergreifenden Suche (CCS) Lookup Join:</strong></p><p>Als Lookup Join in den Versionen 8.19 und 9.1 allgemein verfügbar wurde, fehlte die Unterstützung für die clusterübergreifende Suche (CCS). Für Organisationen, die in mehreren Clustern arbeiten, lässt sich LOOKUP JOIN in 9.2 jetzt nahtlos in CCS integrieren. Platzieren Sie einfach Ihren Lookup-Index auf allen Remote-Clustern, mit denen Sie einen Join durchführen möchten, und ES|QL nutzt diese Remote-Lookup-Indizes automatisch, um den Join mit Ihren Remote-Daten durchzuführen. Dies vereinfacht die verteilte Datenanalyse und gewährleistet eine konsistente Anreicherung Ihres gesamten Elasticsearch-Deployments.</p><p>Diese Verbesserungen ermöglichen es Ihnen, vielfältige Datensätze mit beispielloser Präzision, Geschwindigkeit und Leichtigkeit zu korrelieren und so tiefere, umsetzbare Einblicke ohne komplexe Workarounds oder Vorverarbeitungsschritte zu gewinnen.</p><h2>Reichern Sie Ihre Daten mühelos an: Kibana Discover UX für Lookup-Indizes</h2><p>Die Datenanreicherung sollte unkompliziert sein und keine Hürde darstellen. Wir haben in Kibana Discover eine fantastische neue Nutzererfahrung für die Erstellung und Verwaltung von Lookup-Indizes eingeführt.</p><p><strong>Intuitiver Workflow:</strong> Die umfassende Autovervollständigung von Discover führt Sie durch den Prozess, schlägt Suchindizes und Join-Felder im ES|QL-Editor vor und macht es unglaublich einfach, Ihre hochgeladenen Daten mit vorhandenen Indizes zu verbinden. Geben Sie den Namen eines Lookup-Index ein, der nicht existiert, und erhalten Sie mit einem Klick direkten Zugriff auf den Lookup-Editor, um den Index zu erstellen. Geben Sie den Namen eines bestehenden Nachschlageindex ein, und wir schlagen eine Option zur Bearbeitung vor:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt20a75bcfd25eb156/6a17f1a46864a4864db688a1/d36fd6ffd6bc0bf8d31067f6266445c68d15c71c-1400x184.png" alt="" /><p><strong>Inline-Management (CRUD):</strong> Halten Sie Ihre Datensätze mit Inline-Bearbeitungsfunktionen (Erstellen, Lesen, Aktualisieren, Löschen) und Liniendiagramm direkt in Discover auf dem neuesten Stand.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6263c5dd8c2c9d7e/6a17f1a5af47b614dbcde095/a0e4aa66540b1f725c24ccb0519d978415073bb6-1453x842.png" alt="Beispiel für eine LOOKUP-Abfrage" /><p><strong>Müheloses Hochladen von Dateien: </strong>Sie können jetzt Dateien wie CSVs direkt in Discover hochladen und sofort in Ihren <code>LOOKUP JOIN</code> verwenden. Keine Kontextwechsel mehr durch das Springen zwischen verschiedenen Bereichen von Kibana!</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltddfcc3580af0e5c6/6a17f1a73e9e45965aba1587/0f5dc2c712af4c4cada50292a7c8b836eb02aa67-1600x748.png" alt="Fügen Sie einfach Daten zu einem Lookup-Index hinzu und verwenden Sie sie in LOOKUP-JOINS." /><p>Egal, ob Sie Nutzer-IDs mit Namen mappen, Geschäfts-Metadaten hinzufügen oder statische Referenzdateien verknüpfen – dieses Feature demokratisiert die Datenanreicherung und versorgt die Joins direkt in den Händen aller Nutzer:innen mit Energie – schnell, einfach und alles an einem Ort.</p><h2>Bewahren Sie Ihren Kontext: Einführung von INLINE STATS (technische Vorschau)</h2><p>Die Aggregation von Daten ist entscheidend, aber manchmal müssen Sie die Aggregate <em>neben</em> Ihren ursprünglichen Daten sehen. Wir freuen uns, <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/inlinestats-by">INLINE STATS</a> als <strong>Tech Preview</strong>-Feature vorzustellen.</p><p>Im Gegensatz zum Befehl <code>STATS</code>, der Ihre Eingabefelder durch aggregierte Ausgaben ersetzt, behält <code>INLINE STATS</code> alle Ihre ursprünglichen Eingabefelder bei und fügt lediglich die neuen aggregierten Felder hinzu. Dies ermöglicht es Ihnen, <em>nach</em> der Aggregation weitere Operationen auf Ihren ursprünglichen Eingabefeldern durchzuführen und bietet so einen kontinuierlicheren und flexibleren Analyse-Workflow.</p><p>Um beispielsweise die durchschnittliche Flugdistanz unter Beibehaltung der einzelnen Flugreihen zu berechnen:</p>FROM kibana_sample_data_flights
 | KEEP Carrier, Dest, DistanceMiles
 | INLINE STATS avgDist = ROUND(AVG(DistanceMiles))
       BY Dest
 | WHERE DistanceMiles &gt; avgDist<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9e0c7209db8a67ad/6a17f1a9e8fbcee5233a1a53/6eea943035e0ab371270084c504a06bb89f8b82b-1496x290.png" alt="Filtern von Flugergebnissen mit einer Distanz größer als dem Durchschnitt unter Verwendung von avgDist " /><p>Bei dieser Abfrage wird jeder Zeile <code>avgDist</code> mit der entsprechenden <code>Dest</code>(ination) hinzugefügt, nach der wir gruppiert haben. Da wir dann immer noch die Spalten mit den Fluginformationen haben, können wir die Ergebnisse auf die Flüge mit einer Entfernung, die größer als der Durchschnitt ist, filtern.</p><h2>Zeitreihenunterstützung in ES|QL (technische Vorschau)</h2><p>Elasticsearch verwendet <a href="https://www.elastic.co/docs/manage-data/data-store/data-streams/time-series-data-stream-tsds">Zeitreihen-Datenströme</a> zum Speichern von Metriken. Wir fügen Unterstützung für Zeitreihenaggregationen in ES|QL über den <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/ts"><code>TS</code></a> Source-Befehl hinzu. Dies ist in Elastic Cloud Serverless und 9.2 Basic als Tech-Vorschau verfügbar.</p><p>Die Zeitreihenanalyse basiert größtenteils auf Aggregationsabfragen, die Metrikwerte in Zeit-Buckets zusammenfassen, unterteilt durch eine oder mehrere Filterdimensionen. Die meisten Aggregationsabfragen basieren auf einer zweistufigen Verarbeitung: (a) eine innere Aggregationsfunktion, die Werte pro Zeitreihe zusammenfasst, und (b) eine äußere Aggregationsfunktion, die die Ergebnisse von (a) über Zeitreihen hinweg kombiniert.</p><p>Der Quellbefehl <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/ts"><code>TS</code></a> bietet in Kombination mit <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/stats-by"><code>STATS</code></a> eine prägnante und dennoch effektive Möglichkeit, solche Abfragen über Zeitreihen auszudrücken. Betrachten wir konkreter das folgende Beispiel zur Berechnung der Gesamtanforderungsrate pro Host und Stunde:</p>TS my_metrics
| WHERE @timestamp &gt; NOW() - 1 day
| STATS SUM(RATE(requests))
      BY host, TBUCKET(1h)<p>In diesem Fall wird die Aggregationsfunktion <code>RATE</code> zuerst pro Zeitreihe und Stunde ausgewertet. Die erzeugten Teilaggregate werden dann mit <code>SUM</code> kombiniert, um die endgültigen Aggregatwerte pro Host und Stunde zu berechnen.</p><p>Eine Liste der verfügbaren Funktionen zur Aggregation von Zeitreihen finden Sie <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/time-series-aggregation-functions">hier</a>. <a href="https://www.elastic.co/docs/manage-data/data-store/data-streams/time-series-data-stream-tsds#time-series-metric">Zählerrate</a> wird jetzt unterstützt, die wohl wichtigste Aggregationsfunktion für die Verarbeitung von Zählern.</p><p>Der Quellbefehl <code>TS</code> ist so konzipiert, dass er mit <code>STATS</code> kombiniert werden kann, wobei die Ausführung so abgestimmt ist, dass sie Zeitreihenaggregationen effizient unterstützt. Zum Beispiel werden die Daten sortiert, bevor sie in die <code>STATS</code> gelangen. Verarbeitungsbefehle, die die Zeitreihendaten oder ihre Reihenfolge anreichern oder verändern können, wie <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/fork"><code>FORK</code></a> oder <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/inlinestats-by"><code>INLINE STATS</code></a>, sind derzeit zwischen <code>TS</code> und <code>STATS</code> nicht zulässig. Diese Beschränkung könnte in Zukunft aufgehoben werden.</p><p>Die tabellarische Ausgabe von <code>STATS</code> kann mit einem beliebigen Befehl weiterverarbeitet werden. Zum Beispiel berechnet die folgende Abfrage das Verhältnis des durchschnittlichen <code>cpu_usage</code> pro Host und Stunde bis zum maximalen Wert pro Host:</p>TS my_metrics
| STATS avg_usage = AVG(AVG_OVER_TIME(cpu_usage))
      BY host, time_bucket = TBUCKET(1h)
| INLINE STATS max_avg_usage = MAX(avg_usage)
      BY host
| EVAL ratio = avg_usage / max_avg_usage
| KEEP host, time_bucket, ratio
| SORT host, time_bucket DESC<p>Zeitreihendaten werden auf unserer zugrunde liegenden spaltenförmigen Speicher-Engine gespeichert, die von Lucene-Doc-Werten betrieben wird. Der TS-Befehl fügt die vektorisierte Abfrageausführung über die ES|QL-Compute-Engine hinzu. Die Abfrageleistung wird im Vergleich zu äquivalenten <a href="https://www.elastic.co/docs/reference/query-languages/querydsl">DSL</a>-Abfragen oft um mehr als eine Größenordnung verbessert und ist mit etablierten, metrikspezifischen Systemen vergleichbar. Wir werden in Zukunft eine detaillierte Architektur- und Leistungsanalyse bereitstellen, also bleiben Sie gespannt.</p><h2>Erweiterung Ihres Toolkits: Neue ES|QL-Funktionen</h2><p>Zur weiteren Verbesserung der Nützlichkeit und Vielseitigkeit von ES|QL haben wir eine Reihe neuer <a href="https://www.elastic.co/docs/reference/query-languages/esql/esql-functions-operators">Funktionen</a> hinzugefügt:</p><p><strong>Zeichenfolgenmanipulation: </strong><a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/string-functions#esql-contains">CONTAINS</a>, <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/mv-functions#esql-mv_contains">MV_CONTAINS</a>, <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/string-functions#esql-url_encode">URL_ENCODE</a>, <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/string-functions#esql-url_encode_component">URL_ENCODE_COMPONENT</a>, <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/string-functions#esql-url_decode">URL_DECODE</a> für eine robustere Text- und URL-Verarbeitung.</p><p><strong>Zeitreihen und Geodaten:</strong> <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/grouping-functions#esql-tbucket">TBUCKET</a> für flexible Buckets, TO_DENSE_VECTOR für Vektoroperationen und ein umfassender Satz von <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/spatial-functions">Geodatenfunktionen</a> wie <code>ST_GEOHASH</code>, <code>ST_GEOTILE</code>, <code>ST_GEOHEX</code>, <code>TO_GEOHASH</code>, <code>TO_GEOTILE</code>, <code>TO_GEOHEX</code> für fortgeschrittene ortsbezogene Analysen.</p><p><strong>Datumsformatierung:</strong> <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/date-time-functions#esql-day_name">DAY_NAME</a>, <a href="https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/date-time-functions#esql-month_name">MONTH_NAME</a> für besser lesbare Datumsdarstellungen.</p><p>Diese Funktionen bieten Ihnen eine umfangreichere Auswahl an Werkzeugen, um Ihre Daten direkt innerhalb von ES|QL zu bearbeiten und zu analysieren.</p><h2>Unter der Haube: Mehr Leistung und Effizienz</h2><p>Neben den hervorgehobenen Features bietet Elasticsearch 9.2 zahlreiche Leistungsoptimierungen für ES|QL. Wir haben <a href="https://www.elastic.co/docs/reference/query-languages/esql/commands/where#like-and-rlike">RLIKE (LIST)</a> mit Pushdown beschleunigt, wenn die Funktion mehrere ähnliche RLIKE-Abfragen in einem Ticket ersetzt. Mit <code>RLIKE</code> (LIST) können wir diese Abfragen zu einem einzigen Automaten zusammenführen und einen Automaten anstelle mehrerer anwenden. Wir bieten außerdem ein schnelleres Laden von Schlüsselwortfeldern durch Indexsortierungen und allgemeine Abfrageoptimierungen – diese Verbesserungen gewährleisten, dass Ihre ES|QL-Abfragen effizienter als je zuvor ausgeführt werden.</p><h2>Legen Sie noch heute los!</h2><p>Elasticsearch 9.2 ist ein bedeutender Fortschritt für ES|QL und bringt beispiellose Leistung und Flexibilität in Ihre Datenanalyse-Workflows. Wir ermutigen Sie, diese neuen Features zu erkunden und den Unterschied selbst zu erleben.</p><p>Eine vollständige Liste aller Änderungen und Verbesserungen in Elasticsearch 9.2 finden Sie in den <a href="https://www.elastic.co/guide/en/elasticsearch/reference/9.2/release-notes-9.2.0.html">offiziellen Versionshinweisen</a>. Viel Spaß beim Abfragen!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/esql-elasticsearch-9-2-multi-field-joins-ts-command</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/esql-elasticsearch-9-2-multi-field-joins-ts-command</guid>
    <category><![CDATA[ES|QL]]></category>
    <dc:creator><![CDATA[Tyler Perkins,Kostas Krikellas,Julian Kiryakov]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd30ea8cac3809cc3/6a17f1aa4b055dd8734322f8/415894e21e7758c907d6e60d4efc94230349beef-2012x1164.png" length="0" type="image/png"/>
    <pubDate>Tue, 02 Dec 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearchs ES|QL-Editor-Benutzererfahrung im Vergleich zum PPL-Ereignisanalysator von OpenSearch.]]></title>
    <description><![CDATA[Entdecken Sie, wie die erweiterten Funktionen des ES|QL Editors Ihren Workflow beschleunigen und sich damit deutlich vom manuellen Ansatz des PPL Event Analyzer von OpenSearch abheben. 
]]></description>
    <content:encoded><![CDATA[<p>Die <a href="https://www.elastic.co/blog/getting-started-elasticsearch-query-language">Elasticsearch Query Language</a> (ES|QL), die seit Version 8.14 allgemein verfügbar ist, stellt eine speziell entwickelte Abfragesprache und -engine dar, die für die Bereiche Suche, Beobachtbarkeit und Sicherheitsuntersuchungen konzipiert wurde. Im Gegensatz zur Piped Processing Language (PPL) von OpenSearch, die sich stark an bestehenden Piped-Sprachen orientiert, wurde ES|QL von Grund auf neu entwickelt, um den Fokus auf Eleganz, Benutzerfreundlichkeit und nahtlose Integration in die Kibana-Plattform zu legen.</p><p>In diesem Blogbeitrag werden wir die Entwicklererfahrung des ES|QL-Editors in Elasticsearch 9.1 untersuchen, indem wir sie mit PPL im Event Analyzer (kurz PPL) in OpenSearch 3.2 vergleichen.</p><p>Die Unterschiede werden schnell deutlich: Der ES|QL Editor bietet intelligente Autovervollständigung, kontextbezogene Hilfe, empfohlene Abfragen und clusterübergreifende Abfrageunterstützung, die nicht nur Anfängern, sondern auch Experten gleichermaßen zugutekommen. Das durchdachte Design für die ES|QL-Erstellung zeigt sich auch in der integrierten Abfrageprüfung und der ganzheitlichen Integration durch Kibana-Workflows, beispielsweise mit den zuletzt verwendeten Abfragen.</p><p>PPL hingegen bietet keine vergleichbare Unterstützung für Autovervollständigung, kontextbezogene Hilfestellungen und verteilte Abfragen, was zu einer steileren Lernkurve und mehr Versuch und Irrtum führt.</p><h2>ES|QL einfacher zu erlernen und anzuwenden</h2><p>Der Einstieg in eine neue Abfragesprache kann oft überwältigend sein. Der direkt in <strong>Kibana</strong><strong> Discover</strong> integrierte ES|QL - Editor wurde entwickelt, um diesen Prozess zu vereinfachen, indem er nicht nur die Erstellung und das Debuggen von Abfragen unterstützt, sondern auch beschleunigt, wie schnell Sie sich mit der Sprache vertraut machen und sich damit wohlfühlen. Da der Editor dazu beiträgt, Reibungsverluste bei alltäglichen Aufgaben zu reduzieren, können Sie Ihren Fokus von Syntax und Versuch-und-Irrtum-Prinzip auf die Lösungsfindung verlagern. Mehr über diese Prinzipien und wie wir sie in den Editor integriert haben, können Sie <a href="https://www.elastic.co/search-labs/blog/improving-esql-editor-experience-in-kibana">hier</a> lesen.</p><p>Diese Editor-Oberfläche ist nicht auf Discover beschränkt; es handelt sich um ein wiederverwendbares Code-Modul, dessen <strong>Integration in andere Teile von Kibana</strong> wir gerade vorantreiben, wie zum Beispiel Dashboards, Kibana-Alerts und Kibana-Maps.</p><h3>Intelligente Autovervollständigung: Beschleunigt die Erstellung Ihrer Suchanfragen</h3><p>Die Autovervollständigung im ES|QL Editor ist umfassend und bietet Vorschläge für kompatible Funktionen, Argumente, Literale und sogar verschachtelte Funktionen – eine Fähigkeit, die in PPL deutlich fehlt. Tatsächlich wurde es von Grund auf neu aufgebaut, wie <a href="https://www.elastic.co/search-labs/blog/esql-autocomplete-rebuilt">hier</a> beschrieben.</p><p>Die Validierung läuft während der Eingabe durch den Benutzer, wie <a href="https://www.elastic.co/search-labs/blog/improving-esql-editor-experience-in-kibana">hier</a> beschrieben, und schlägt Felder vor sowie benachrichtigt den Benutzer über Fehler. Dies reduziert die mentale Belastung der Benutzer und hilft, Fehler frühzeitig im Abfrageerstellungsprozess zu vermeiden.</p><p>Beispiel: In dieser Verschachtelung werden Felder und kompatible Funktionen vorgeschlagen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb186fc80dcc66f5/6a17f311e9ea8737a5a9c720/a4d7b2819c34fab31bced7873257b8932b623fba-1502x473.png" alt="Vorschlag zur Verschachtelung von Feldern und kompatiblen Funktionen." /><p>Etwas, das PPL nicht unterstützt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt250ae79e8f33b598/6a17f3127f6f150d3dc09c74/6f3a89b1255b8a3a762022a2704fdd1c2987e5f9-1013x335.png" alt="Eine Funktion, die PPL nicht unterstützt." /><p>Selbst wenn eine intelligente Autovervollständigung Sie durch kompatible Funktionen, Argumente und verschachtelte Funktionen führt, möchten Sie vielleicht trotzdem ein tieferes Verständnis der verfügbaren Optionen. Genau hier erweist sich die kontextbezogene Hilfe des ES|QL Editors als unschätzbar wertvoll, da sie sofortige Unterstützung direkt im Editor bietet, um Ihre Abfrageentwicklung zu verdeutlichen und zu verbessern.</p><h3>Kontextbezogene Hilfe direkt zur Hand</h3><p>Zusätzliche Informationen zu einem durch die Autovervollständigung generierten Befehl erhalten Sie mit einem Klick Strg+Leertaste. Es erscheint sofort ein Fenster mit Details zu der betreffenden Funktion, dem Argument oder dem Feld. Diese unkomplizierte Interaktion hält die Entwickler im Arbeitsfluss und bietet ihnen bedarfsgerechte Hilfestellung, ohne dass sie den Editor verlassen oder externe Dokumentationen durchsuchen müssen. Dadurch wird der Zeitaufwand für Syntaxprüfungen reduziert und häufige Fehler werden vermieden, bevor sie überhaupt auftreten.</p><p>So sieht es in der Praxis aus:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt407e42acc7f53f15/6a17f3134b055d128d43231a/2797f9b5e002dbd83c46475c4ed4dcdc86144a01-1343x522.gif" alt="Ein Befehl, der durch die Autovervollständigung mit Strg+Leertaste für zusätzlichen Kontext generiert wurde." /><p>PPL bietet diese Art von integrierter Anleitung nicht, sodass die Benutzer auf externe Dokumente oder das Ausprobieren angewiesen sind. Dieses Fehlen ist nicht nur ein fehlendes Merkmal; es verdeutlicht eine umfassendere Diskrepanz in der Designphilosophie. ES|QL legt Wert auf ein durchdachtes, kontextbezogenes Benutzererlebnis, das sich an die Daten und Arbeitsabläufe des Benutzers anpasst. Dieser Unterschied wird umso deutlicher, je komplexer die Abfragen werden, wodurch der ES|QL Editor eine effizientere und zuverlässigere Umgebung sowohl für Lernzwecke als auch für den Produktiveinsatz darstellt.</p><h3>Empfohlene Abfragen, die den Datenkontext berücksichtigen</h3><p>Der ES|QL-Editor bietet empfohlene Abfragen, die automatisch auf die Daten, mit denen Sie arbeiten, wie z. B. Protokolle, zugeschnitten sind. Statt eines leeren Editors werden die relevantesten Ausgangspunkte für gängige Anwendungsfälle angezeigt. Durch die Auswahl einer empfohlenen Abfrage wird eine kanonische Abfrage generiert, die sofort verwendbar ist und bei Bedarf weiter verfeinert werden kann. Dieser Ansatz beschleunigt die Abfrageentwicklung, insbesondere für neue Benutzer, die die vollständige Syntax möglicherweise noch nicht kennen.</p><p>Hier ist ein Beispiel, bei dem ein Benutzer die Abfrage „Änderungspunkt erkennen“ auswählt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc6c41f9e1e3cb40/6a17f3156864a43791b688d0/3284c9340d41298820fbf8c7702abad946b48248-925x370.gif" alt="Was passiert, wenn ein Benutzer die Abfrage „Änderungspunkt erkennen“ auswählt?" /><p>Vergleichen Sie das mit der PPL-Erfahrung:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6511bb51659feaf3/6a17f3166864a427c2b688d4/5c3e59dadc6210aede3366bdd081887bcbae7a54-969x798.png" alt="Das PPL-Erlebnis, allerdings nur mit grundlegender Autovervollständigung." /><p>Im Gegensatz dazu bietet PPL hier nur eine einfache Autovervollständigung, sodass man Abfragen ohne Kontext oder Struktur selbst zusammensetzen muss. Dieser Mangel an Anleitung kann zu Frustration und dem Vorgehen nach dem Prinzip „Versuch und Irrtum“ führen.
Mit den datenbasierten empfohlenen Abfragen des ES|QL-Editors können Sie vermeiden, bei Routineaufgaben von Grund auf neu zu beginnen oder sich Syntax einzuprägen. Der Editor reduziert die kognitive Belastung, hilft, Fehler zu vermeiden, und ermöglicht es Ihnen, sich auf die Problemlösung und übergeordnete Ziele wie die Durchführung clusterübergreifender Suchen zu konzentrieren, anstatt sich mit der Formulierung von Abfragen auseinanderzusetzen.</p><h2>Intuitive clusterübergreifende Abfragen</h2><p>Die Autovervollständigung des ES|QL-Editors ist auch bei der Arbeit mit mehreren Remote-Clustern <a href="https://elastic.aiops.work/search-labs/blog/esql-cross-cluster-search">mit CCS</a> weiterhin überlegen. Hier ist der Grund:</p><h3>Der ES|QL-Editor bietet nahtlose Autovervollständigung auch clusterübergreifend.</h3><p>Die Autovervollständigung im ES|QL-Editor unterstützt nicht nur Clusternamen, sondern auch<strong> lokale und Remote-Indizes</strong>. Wie <a href="https://www.elastic.co/search-labs/blog/esql-cross-cluster-search">hier</a> beschrieben, funktioniert dies dank einer Koordinatorknotenarchitektur, die dabei hilft, den Abfrageplan zu validieren und zu generieren, der an die lokalen Knoten gesendet wird, die Abfrage auszuführen und die Ergebnisse zu aggregieren, bevor sie an den Benutzer zurückgesendet werden. Ohne Eingabe des vollständigen Namens des Remote-Clusters startet die Eingabe von „:“ den Autovervollständigungsprozess für den Remote-Index. Und Sie sind nicht auf das Präfix beschränkt.</p><p>Dadurch wird es einfach, verteilte Datensätze zu finden und abzufragen, ohne sich Namenskonventionen merken oder den Kontext wechseln zu müssen.</p><p>Hier ist ein Beispiel, bei dem der Benutzer einfach „clu:g“ eingibt, um einen Remote-Index zu finden:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4fadd61aa6d2a212/6a17f3186864a4a385b688d8/bae1fbacb2320e4d07f41291ea57c9bcf15bf8a5-1092x523.gif" alt="Ein Beispiel, bei dem der Benutzer einfach „clu:g“ eingibt, um einen entfernten Index zu finden." /><p>Im krassen Gegensatz dazu bietet die PPL nur eine grundlegende Vervollständigung für lokale Indizes, wobei die Vorschläge auf Präfixübereinstimmungen beschränkt sind. Remote-Cluster müssen manuell eingegeben werden, was die Fehlerwahrscheinlichkeit erhöht und die Abfrageerstellung verlangsamt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3949402084cf303a/6a17f31a6864a482b1b688dc/e38793c0cc7c6cc7dc0fd4779a3e24ffbb6e0838-1094x263.gif" alt="Ein Beispiel dafür, wie PPL nur eine grundlegende Vervollständigung für lokale Indizes bietet, wobei die Vorschläge auf Präfixübereinstimmungen beschränkt sind." /><p>PPL bietet Vervollständigung nur für lokale Indizes und die Vorschläge sind auf das Präfix beschränkt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcaa81c403f354e1f/6a17f31c6864a4e620b688e0/5310f824942f94485cace2558ea72c56a0971e22-862x197.png" alt="Ein weiteres Beispiel dafür, wie PPL nur für lokale Indizes Vervollständigungen bereitstellt und Vorschläge auf das Präfix beschränkt sind." /><p>ES|QL geht noch einen Schritt weiter, indem <a href="https://www.elastic.co/docs/solutions/search/cross-cluster-search#exclude-problematic-clusters">es Ausschlüsse direkt über ein negatives Vorzeichen ermöglicht</a> und Ihnen so eine detaillierte Kontrolle darüber gibt, welche Cluster in Ihre Untersuchung einbezogen werden. Diese Funktionalität ist besonders wertvoll bei der Arbeit mit hybriden Umgebungen, in denen Sie bei clusterübergreifenden Untersuchungen möglicherweise bestimmte Datensätze ein- oder ausschließen möchten.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf0ca78bfbceb60ae/6a17f31d6864a4199bb688e4/f23ca17f58fbf8e6d27419c028274cb91f30a549-937x78.png" alt="Ein Codebeispiel für eine clusterübergreifende Untersuchung." /><p>Diese Verbesserungen spiegeln den umfassenderen Fokus von Elasticsearch auf die Reduzierung von Reibungsverlusten bei der clusterübergreifenden Suche wider. Durch die Vereinfachung der Erstellung und Verwaltung verteilter Abfragen ermöglicht der ES|QL Editor Analysten und Entwicklern, sich auf Erkenntnisse anstatt auf die Syntax zu konzentrieren, während PPL diese Last eher dem Benutzer überlässt. Und genau wie der ES|QL-Editor die Erstellung clusterübergreifender Abfragen vereinfacht, bietet er auch Werkzeuge zur Überprüfung der Ausführung dieser Abfragen und gewährleistet so Transparenz und Leistungsüberwachung über mehrere Cluster hinweg.</p><h3>Analyse der Details der clusterübergreifenden Suche mithilfe des Inspektionstools</h3><p>Das Inspektionstool, das über den ES|QL-Editor zugänglich ist, dient dazu, Metadaten mit expliziten Informationen über die Abfrageausführung in allen Clustern bereitzustellen. Diese Funktionalität ist in Kibana Discover aktiviert und direkt im Query Inspector zugänglich. Dadurch können Sie den Suchfortschritt und Details analysieren, was insbesondere für <strong>die Cross-Cluster Search</strong> (<a href="https://www.elastic.co/docs/reference/query-languages/esql/esql-cross-clusters">CCS</a>) von entscheidender Bedeutung ist. Diese Funktion hilft Ihnen, den Suchfortschritt zu überwachen und zu verstehen, wie Abfragen in verteilten Datensätzen abschneiden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf79eaeedac3600b9/6a17f31fabe0f26f06dfeb4b/5d1c204f70171526fff924c30ea8ad08121a0f8d-919x523.gif" alt="Das Inspektionstool zur Analyse von Details der clusterübergreifenden Suche." /><p>Diese detaillierte Transparenz der Abfrageausführung, insbesondere bei komplexen verteilten Suchvorgängen, ermöglicht es Ihnen, optimale Leistung und Fehlerbehebung zu gewährleisten.</p><p>Über das Verständnis der Funktionsweise einzelner Abfragen hinaus verbessert der ES|QL Editor die Benutzererfahrung zusätzlich, indem er wesentliche Funktionalitäten tief in die gesamte Kibana-Plattform einbettet und so einen nahtlosen und unterbrechungsfreien Arbeitsablauf fördert.</p><h2>Einheitliche Abfrageerfahrung mit ES|QL und Kibana</h2><p>Eine der häufigsten Ursachen für Reibungsverluste bei abfragegesteuerter Analyse ist der Kontextwechsel. Oftmals müssen Sie sich an bereits formulierte Anfragen erinnern. Jede Unterbrechung stört die Konzentration und verlangsamt die Ermittlungen. Der ES|QL-Editor löst dieses Problem durch die Integration des Abfrageverlaufs in Kibana.</p><h3>Aktuelle Suchanfragen</h3><p>Die Funktion <a href="https://www.elastic.co/search-labs/blog/esql-piped-query-language-goes-ga">„Letzte Abfragen“</a> im ES|QL Editor hilft Ihnen, im Arbeitsfluss zu bleiben, indem sie frühere Arbeiten sofort zugänglich macht. Im ES|QL-Editor von Discover können Sie Ihre letzten 20 Abfragen anzeigen, erneut ausführen und mit einem Stern markieren. So ist sichergestellt, dass häufig verwendete oder komplexe Abfragen nur einen Klick entfernt sind. Diese gespeicherten Abfragen werden auch in Kibana übernommen und in Dashboards, Visualisierungen, Benachrichtigungen und Karten integriert, sodass Sie Ihren aktuellen Bildschirm nicht verlassen oder Befehle von Grund auf neu eingeben müssen. Dadurch werden sich wiederholende Arbeiten reduziert, die Ermittlungen beschleunigt und das Fehlerrisiko minimiert.</p><p>Ein Benutzer kann beispielsweise die zuletzt verwendeten Abfragen im ES|QL-Editor in Discover nutzen (und diese mit einem Stern markieren):</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt49033a46a0805ec8/6a17f321e9ea87a505a9c724/eb0f9fe37b92dec421c394d31ae7d90afebe062e-1421x793.png" alt="Ein Beispiel für die Verwendung der zuletzt verwendeten Abfragen im ES|QL-Editor in discover (und wie man sie mit einem Stern markiert)." /><p>Die neuesten Suchanfragen sind im Dashboard integriert:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta2f7c745cdc5e5f1/6a17f323a2929932a1d02da9/b84cd3a9bdec58812360d2aba4fc7713363ee3cc-1411x797.png" alt=" Aktuelle Suchanfragen in einem Dashboard integriert." /><p>PPL bietet keine vergleichbare Funktion, sodass Benutzer auf manuelles Kopieren und Einfügen oder externe Notizen angewiesen sind, um Abfragen wiederzuverwenden. Der Unterschied liegt nicht nur in der Bequemlichkeit; er spiegelt die Strategie von Elastic wider, ES|QL als eine wirklich integrierte Sprache innerhalb des Kibana-Ökosystems aufzubauen. Mit Funktionen wie „Letzte Abfragen“ optimiert der ES|QL Editor nicht nur die täglichen Arbeitsabläufe, sondern legt auch den Grundstein für fortgeschrittenere Funktionen, die sich derzeit in der technischen Vorschau befinden, und gewährleistet so eine kontinuierliche Weiterentwicklung des Benutzererlebnisses.</p><h2>Fazit</h2><p>ES|QL ist mehr als nur eine Syntax; es spiegelt die Strategie von Elastic wider, die Art und Weise zu verbessern, wie Benutzer Daten suchen, erkunden und analysieren. Mit intelligenter Autovervollständigung, kontextbezogenen empfohlenen Abfragen, Hilfestellungen im Editor und Tools wie Inspect beschleunigt der ES|QL Editor das Lernen, reduziert Fehler und vereinfacht komplexe Arbeitsabläufe wie die Clusterübergreifende Analyse. Die Integration in Kibana ermöglicht die nahtlose Verbindung von Abfragen mit Dashboards, Warnmeldungen und Visualisierungen für einen unterbrechungsfreien Workflow.</p><p>Zusammenfassend lässt sich sagen, dass ES|QL nicht einfach nur eine weitere Pipe-Sprache ist; es ist eine durchdacht entwickelte Abfrage-Engine in Verbindung mit einer intuitiven Benutzeroberfläche, die die Art und Weise, wie Sie mit Ihren Daten interagieren, grundlegend neu definiert und ein integriertes, intelligentes und sich ständig weiterentwickelndes Erlebnis bietet, das sich deutlich von der oft sequenziellen und weniger geführten Natur von OpenSearch PPL abhebt.</p><h2>Was kommt als Nächstes?</h2><p>Dieser Blog kratzt nur an der Oberfläche von ES|QL. Zukünftige Beiträge werden sich eingehender mit Vergleichen mit OpenSearch PPL befassen und Geodaten-, Visualisierungs- und kommende Editorfunktionen wie <a href="https://www.elastic.co/docs/explore-analyze/dashboards/add-controls">Controls</a> (bereits in Dashboards verfügbar), Registerkarten zur Erkundung mehrerer Daten, Hintergrundsuche, erweiterte Abfragehistorie und FUSE untersuchen.</p><h2>Testen Sie ES|QL noch heute!</h2><p>Sie können ES|QL in vollständig verwalteten Elasticsearch <a href="https://www.elastic.co/cloud/serverless">Serverless</a> -Projekten mit einer <a href="https://www.elastic.co/docs/deploy-manage/deploy/elastic-cloud/create-serverless-project">kostenlosen Testversion</a> ausprobieren. Es ist auch in Versionen ab 8.11 verfügbar, bietet aber das beste Nutzungserlebnis in den <a href="https://www.elastic.co/blog/whats-new-elastic-9-1-0">Versionen 8.19 und 9.1</a>.</p><p>Legen Sie in wenigen Minuten in Ihrer lokalen Umgebung mit einem einzigen Befehl los:</p>curl -fsSL https://elastic.co/start-local | sh]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-ppl-esql</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-ppl-esql</guid>
    <category><![CDATA[ES|QL]]></category>
    <dc:creator><![CDATA[Libby Lin,George Kobar]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte51b193824ff8084/6a17f3257f6f154b7bc09c7c/f1ff4ff4a00b3e5b084d4116cea6cabc82a2d816-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 18 Sep 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Einführung des ES|QL-Abfragegenerators für den Elasticsearch Ruby Client]]></title>
    <description><![CDATA[Lernen Sie, wie Sie den kürzlich veröffentlichten ES|QL-Abfragegenerator für den Elasticsearch Ruby Client verwenden. Ein Tool, um ES|QL-Abfragen mit Ruby-Code einfacher zu erstellen.]]></description>
    <content:encoded><![CDATA[<p>Wir haben kürzlich <a href="https://github.com/elastic/esql-ruby/"><code>elastic-esql</code></a> veröffentlicht, ein Ruby-Gem, das unter der Apache 2-Lizenz veröffentlicht wurde. Dieses Juwel ermöglicht es Ihnen, Elastic <a href="https://www.elastic.co/docs/explore-analyze/query-filter/languages/esql">ES|QL-</a> Abfragen in idiomatischem Ruby zu erstellen, die Sie dann mit der ES|QL-Abfrage-API verwenden können. ES|QL ermöglicht es Entwicklern, in Elasticsearch gespeicherte Daten mittels Abfragen zu filtern, zu transformieren und zu analysieren. Es verwendet "Pipes" ( <code>|</code> ), um die Daten schrittweise zu verarbeiten. Das Gem verwendet stattdessen Ruby-Funktionen, die Sie an das ursprüngliche Objekt anhängen können, um komplexere Abfragen zu erstellen:</p><p><strong>ESQL:</strong></p><p><strong>Rubin:</strong></p>Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending<h2>Installation</h2><p>Das Gem kann über RubyGems installiert werden mit:</p>gem install elastic-esql<p>Alternativ kann es der Gemfile-Datei eines Projekts hinzugefügt werden:</p>gem 'elastic-esql'<h2>Verwendung</h2><p>Sie können entweder eine vollständige Abfrage auf einmal erstellen oder ein Abfrageobjekt mit einem Quellbefehl wie <code>from</code> oder <code>row</code> erstellen und dann ES|QL-Methoden verketten, um darauf aufzubauen.</p>query = Elastic::ESQL.from('sample_data')
query.limit(2).sort('@timestamp')<p>Das Gem übersetzt den Code in ES|QL für die <code>to_s</code> -Methode, sodass es die ES|QL-Abfrage zurückgibt, wenn sie ausgegeben oder als String gecastet wird:</p>query = Elastic::ESQL.from('sample_data').limit(2).sort('@timestamp').descending
query.to_s
# =&gt; "FROM sample_data | LIMIT 2 | SORT @timestamp DESC"<p>Sie können ein Abfrageobjekt instanziieren und seinen Anfangszustand verändern, indem Sie die <code>!</code> -Äquivalente jeder Funktion verwenden:</p>query = Elastic::ESQL.from('sample_data')
query.to_s
# =&gt; "FROM sample_data"
query.limit!(2).sort!('@timestamp')
query.to_s
# =&gt; "FROM sample_data | LIMIT 2 | SORT @timestamp"<p>Das Tool bietet bequeme Möglichkeiten, zusätzliche Schritte an eine ES|QL-Funktion anzuhängen, wie z. B. <code>enrich</code> und <code>sort</code>. Sobald Sie <code>enrich</code> auf einem <code>Elastic::ESQL</code> -Objekt aufgerufen haben, können Sie <code>on</code> und <code>with</code> daran anhängen:</p>esql.enrich!('policy').on('a').with({ name: 'language_name' })<p>Sie können auch <code>desc</code>, <code>asc</code>, <code>nulls_first</code> und <code>nulls_last</code> an Ihre Abfrage anhängen, nachdem Sie <code>sort</code> verwendet haben:</p>Elastic::ESQL.from('sample_data').sort('@timestamp').asc.to_s
# =&gt; 'FROM sample_data | SORT @timestamp ASC'

Elastic::ESQL.from('sample_data').sort('@timestamp').desc.nulls_first.to_s
# =&gt; 'FROM sample_data | SORT @timestamp DESC NULLS FIRST'<p>Es unterstützt auch benutzerdefinierte Zeichenketten, falls Sie die ES|QL-Abfrage selbst schreiben oder eine Funktion nutzen möchten, die noch nicht in die Bibliothek aufgenommen wurde. <code>custom</code> wird die Zeichenketten am Ende der Abfrage zusammenfügen. Die Zeichen werden beim Senden an die Funktion hinzugefügt, ohne dabei Pipe-Zeichen einzufügen. Sie werden durch ein Leerzeichen mit dem Rest der Anfrage verbunden.</p>esql = Elastic::ESQL.from('sample_data')
esql.custom('| MY_VALUE = "test value"').to_s
# =&gt; 'FROM sample_data | MY_VALUE = "test value"'<p>Sie können auch <code>custom</code> -Funktionen verketten:</p>esql.custom('| MY_VALUE = "test value"').custom('| ANOTHER, VALUE')
'FROM sample_data | MY_VALUE = "test value" | ANOTHER, VALUE'<h2>Verwendung des ES|QL Query Builders mit dem Ruby-Client</h2><p>Sie können den Query Builder direkt mit <a href="https://github.com/elastic/elasticsearch-ruby">elasticsearch-ruby</a> und der <code>esql.query</code> API verwenden, indem Sie das Query-Objekt senden:</p>require 'elasticsearch'
require 'elastic/esql'

client = Elasticsearch::Client.new
index = 'sample_data'

query = Elastic::ESQL.from(index)
                     .sort('@timestamp')
                     .desc
                     .where('event_duration &gt; 5000000')
                     .limit(3)
                     .eval({ duration_ms: 'ROUND(event_duration/1000000.0, 1)' })
client.esql.query(body: { query: query })<p>Sie können es auch mit dem ES|QL-Helper des Elasticsearch Ruby-Clients verwenden. <a href="https://www.elastic.co/search-labs/blog/esql-ruby-helper-elasticsearch">Weitere Informationen finden Sie hier</a>:</p>require 'elasticsearch/helpers/esql_helper'

Elasticsearch::Helpers::ESQLHelper.query(client, query)<h2>Als eigenständiges Werkzeug</h2><p>Das Gem ist als eigenständiges Werkzeug konzipiert, um ES|QL-Abfragen auf idiomatische Weise zu erstellen. Es hat keine Laufzeitabhängigkeiten; Sie können es mit dem offiziellen Elasticsearch Ruby-Client oder auch eigenständig verwenden.</p><p>Die generierte Abfrage kann mit der <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-query"><code>esql.query</code></a> API auf jede Art und Weise verwendet werden, wie eine Anwendung mit der Elasticsearch API interagiert (Ruby oder nicht). Sobald eine Abfrage mit <code>elastic-esql</code> erstellt wurde, kann die generierte Zeichenkette als Parameter <code>query</code> im Anfragetext an die API gesendet werden. </p><p>Ich habe bereits über <a href="https://www.elastic.co/search-labs/blog/elasticsearch-ruby-tools">die Verwendung von Elasticsearch mit gängigen Ruby-Tools</a> geschrieben. Dieses Gem kann mit allen gängigen Ruby-Tools verwendet werden, um Elasticsearch mit ES|QL abzufragen.</p><h2>Fazit</h2><p>Diese Bibliothek befindet sich in aktiver Entwicklung, und die endgültige API ist noch nicht fertiggestellt. Es ist aktuell als technische Vorschauversion veröffentlicht. Sollten Sie Feedback zur aktuellen API oder zur allgemeinen Nutzung haben, zögern Sie bitte nicht <a href="https://github.com/elastic/esql-ruby/issues">, ein neues Issue zu eröffnen</a>. Weitere Informationen zum Ruby ES|QL Query Builder finden Sie in <a href="https://github.com/elastic/esql-ruby/?tab=readme-ov-file#ruby-esql-query-builder">der README-Datei</a> .</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/esql-query-builder-elasticsearch-ruby-client</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/esql-query-builder-elasticsearch-ruby-client</guid>
    <category><![CDATA[ES|QL]]></category>
    <category><![CDATA[Ruby]]></category>
    <dc:creator><![CDATA[Fernando Briano]]></dc:creator>
    <pubDate>Wed, 17 Sep 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Geodaten mit Kibana in Elasticsearch einlesen und in ES|QL verwenden]]></title>
    <description><![CDATA[Wie man Kibana und den CSV-Ingest-Prozessor verwendet, um Geodaten in Elasticsearch einzulesen und damit in der Elasticsearch Query Language (ES|QL) zu suchen. Elasticsearch verfügt über leistungsstarke Geodaten-Suchfunktionen, die nun in ES|QL integriert werden, um die Benutzerfreundlichkeit und OGC-Vertrautheit deutlich zu verbessern. Um diese Funktionen nutzen zu können, benötigen wir jedoch Geodaten.]]></description>
    <content:encoded><![CDATA[<p>Kürzlich haben wir einen Blogbeitrag veröffentlicht, in dem wir die Verwendung der neuen <a href="https://www.elastic.co/search-labs/blog/esql-geospatial-search-part-one">Geodaten-Suchfunktionen</a> <a href="https://www.elastic.co/search-labs/blog/esql-geospatial-search-part-one">in</a> <a href="https://www.elastic.co/search-labs/blog/esql-geospatial-search-part-one">ES|QL</a>, der neuen, leistungsstarken <a href="https://www.elastic.co/search-labs/blog/esql-piped-query-language-goes-ga">Abfragesprache</a> von Elasticsearch, beschreiben. Um diese Funktionen nutzen zu können, benötigen Sie Geodaten in Elasticsearch. In diesem Blogbeitrag zeigen wir Ihnen, wie Sie Geodaten einlesen und in ES|QL-Abfragen verwenden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc041ebca11476c6/6a16f70560084b31b93c4344/01fde3b1d714f12bf8673140c9f2f940d443de31-1440x823.jpg" alt="ESQL-Geodatensuche" /><h2>Importieren von Geodaten mit Kibana</h2><p>Die Daten, die wir für die Beispiele im vorherigen Blog verwendet haben, basierten auf Daten, die wir intern für Integrationstests verwenden. Zu Ihrer Bequemlichkeit haben wir es hier in Form einiger CSV-Dateien beigefügt, die Sie problemlos mit Kibana importieren können. Die Daten setzen sich aus Flughäfen, Städten und Stadtgrenzen zusammen. Sie können die Daten hier herunterladen:</p><ul><li><p><a href="https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/supporting-blog-content/geospatial-data-ingest/airports/airports.csv">airports.csv</a></p><ul><li><p>Dies beinhaltet die Zusammenführung von drei Datensätzen:</p><ul><li><p>Flughäfen (Namen, Standorte und zugehörige Daten) von <a href="https://www.naturalearthdata.com/downloads/10m-cultural-vectors/airports/">Natural Earth</a></p></li><li><p>Stadtstandorte von <a href="https://simplemaps.com/data/world-cities">SimpleMaps</a></p></li><li><p>Flughafenhöhen aus <a href="https://www.partow.net/miscellaneous/airportdatabase/">der globalen Flughafendatenbank</a></p></li></ul></li></ul></li><li><p><a href="https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/supporting-blog-content/geospatial-data-ingest/airports/airport_city_boundaries.csv">airport_city_boundaries.csv</a></p><ul><li><p>Dies beinhaltet eine Zusammenführung der oben genannten Flughafen- und Städtenamen mit einer neuen Quelle:</p><ul><li><p>Stadtgrenzen aus <a href="https://www.openstreetmap.org/">OpenStreetMap</a></p></li></ul></li></ul></li></ul><p>Wie Sie sich vorstellen können, haben wir einige Zeit damit verbracht, diese Datenquellen in den beiden oben genannten Dateien zusammenzuführen, mit dem Ziel, die Geodatenfunktionen von ES|QL testen zu können. Dies entspricht möglicherweise nicht ganz Ihren spezifischen Datenanforderungen, aber hoffentlich gibt Ihnen dies eine Vorstellung davon, was möglich ist. Insbesondere möchten wir einige interessante Dinge demonstrieren:</p><ul><li><p>Importieren von Daten mit Geodatenfeldern zusammen mit anderen indexierbaren Daten</p></li><li><p>Importieren von <code>geo_point</code> und <code>geo_shape</code> -Daten und deren gemeinsame Verwendung in Abfragen</p></li><li><p>Importieren von Daten in zwei Indizes, die über eine räumliche Beziehung verknüpft werden können</p></li><li><p>Erstellung einer Ingest-Pipeline zur Erleichterung zukünftiger Importe (über Kibana hinaus)</p></li><li><p>Einige Beispiele für Ingest-Prozessoren, wie <code>csv</code>, <code>convert</code> und <code>split</code></p></li></ul><p>In diesem Blogbeitrag geht es zwar um die Arbeit mit CSV-Daten, aber es ist wichtig zu verstehen, dass es <a href="https://www.elastic.co/guide/en/kibana/current/import-geospatial-data.html">mehrere Möglichkeiten</a> <a href="https://www.elastic.co/guide/en/kibana/current/import-geospatial-data.html"></a> <a href="https://www.elastic.co/guide/en/kibana/current/import-geospatial-data.html">gibt, Geodaten mit</a> <a href="https://www.elastic.co/guide/en/kibana/current/import-geospatial-data.html">Kibana</a> hinzuzufügen . Innerhalb der Kartenanwendung können Sie durch Trennzeichen getrennte Daten wie CSV, GeoJSON und ESRI ShapeFiles hochladen und auch direkt in der Karte Formen zeichnen. In diesem Blogbeitrag konzentrieren wir uns auf den Import von CSV-Dateien von der Kibana-Startseite.</p><h3>Import der Flughäfen</h3><p>Die erste Datei, <a href="https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/supporting-blog-content/geospatial-data-ingest/airports/airports.csv">airports.csv</a>, hat einige interessante Eigenheiten, mit denen wir uns auseinandersetzen müssen. Erstens weisen die Spalten zusätzliche Leerzeichen als Trennzeichen auf, was für CSV-Dateien untypisch ist. Zweitens handelt es sich bei dem Feld <code>type</code> um ein Mehrwertfeld, das wir in separate Felder aufteilen müssen. Schließlich handelt es sich bei einigen Feldern nicht um Zeichenketten, sondern um Felder, die in den richtigen Datentyp konvertiert werden müssen. All dies kann mithilfe der CSV-Importfunktion von Kibana erfolgen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt393bc416bf425301/6a16f707839dfa1e86dcfca9/b1afd8c95973bec32f229a9adfaef14680b09a8e-1944x478.png" alt="Kibana Upload – Vorschau" /><p>Beginnen Sie auf der Kibana-Startseite. Es gibt einen Abschnitt mit dem Titel „Erste Schritte durch Hinzufügen von Integrationen“, der einen Link mit der Bezeichnung „Datei hochladen“ enthält:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte12fc741edab20d3/6a16f709acf088600fbe98bf/996372bb3a52859cc840bd1d8f984a33a0e7ada3-1180x410.png" alt="Kibana-Startseite – Datei hochladen" /><p>Klicken Sie auf diesen Link, und Sie gelangen zur Seite „Datei hochladen“. Hier können Sie die <code>airports.csv</code> -Datei per Drag &amp; Drop einfügen. Kibana analysiert die Datei und zeigt Ihnen eine Vorschau der Daten an. Das System hätte das Trennzeichen automatisch als Komma und die erste Zeile als Kopfzeile erkennen sollen. Allerdings wurden vermutlich weder die zusätzlichen Leerzeichen zwischen den Spalten entfernt, noch wurden die Typen der Felder bestimmt, da angenommen wurde, dass alle Felder entweder <code>text</code> oder <code>keyword</code> sind. Das müssen wir beheben.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf65a09ec0c7a61ad/6a16f70ad7c0227aedde626f/1d9ffa6cdbc0d67a228be1a747ec1ebda6a63099-1800x538.png" alt="Kibana Upload – Vorschau" /><p>Klicken Sie auf <code>Override settings</code> und aktivieren Sie das Kontrollkästchen für <code>Should trim fields</code>, und anschließend <code>Apply</code> um die Einstellungen zu schließen. Nun müssen wir die Datentypen der Felder korrigieren. Dies ist auf der nächsten Seite verfügbar, also klicken Sie bitte auf <code>Import</code>.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltda9a5f85d8e693dc/6a16f70c60084b72f53c4348/a97aceffb1858eae26a213336913505ae9923b03-1800x526.png" alt="Kibana Upload - Import" /><p>Wählen Sie zuerst einen Indexnamen aus und anschließend <code>Advanced</code> , um zur Seite für Feldzuordnungen und Datenverarbeitung zu gelangen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt56705083cdd9eb18/6a16f70d66c4f93350f8bdbb/058b0fb09da0b8d7f9c9b0a9c83b8b485ce43925-1440x629.png" alt="Kibana Upload – Feldzuordnungen" /><p>Hier müssen wir sowohl die Feldzuordnungen für den Index als auch die Datenaufnahmepipeline anpassen. Erstens hat Kibana wahrscheinlich das Feld <code>scalerank</code> automatisch als <code>long</code> erkannt, aber die Felder <code>location</code> und <code>city_location</code> fälschlicherweise als <code>keyword</code> interpretiert. Ändern Sie sie in <code>geo_point</code>, sodass die Zuordnungen am Ende etwa so aussehen:</p>{
  "properties": {
    "abbrev":        { "type": "keyword" },
    "city":          { "type": "keyword" },
    "city_location": { "type": "geo_point" },
    "country":       { "type": "keyword" },
    "elevation":     { "type": "double" },
    "location":      { "type": "geo_point" },
    "name":          { "type": "text" },
    "scalerank":     { "type": "long" },
    "type":          { "type": "keyword" }
  }
}<p>Sie haben hier eine gewisse Flexibilität, aber beachten Sie, dass die Wahl des Typs Einfluss darauf hat, wie das Feld indiziert wird und welche Art von Abfragen möglich ist. Wenn Sie beispielsweise <code>location</code> auf <code>keyword</code> belassen, können Sie keine Geodaten-Suchanfragen darauf durchführen. Wenn Sie <code>elevation</code> als <code>text</code> belassen, können Sie keine numerischen Bereichsabfragen darauf durchführen.</p><p>Jetzt ist es an der Zeit, die Datenaufnahmepipeline zu reparieren. Falls Kibana <code>scalerank</code> automatisch als <code>long</code> erkannt hat, wurde außerdem ein Prozessor hinzugefügt, um das Feld in <code>long</code> umzuwandeln. Wir müssen einen ähnlichen Prozessor für das Feld <code>elevation</code> hinzufügen, der es diesmal in <code>double</code> umwandelt. Bearbeiten Sie die Pipeline, um sicherzustellen, dass diese Konvertierung vorhanden ist. Bevor wir dies speichern, möchten wir noch eine weitere Konvertierung durchführen, um das Feld <code>type</code> in mehrere Felder aufzuteilen. Fügen Sie der Pipeline einen <code>split</code> -Prozessor mit folgender Konfiguration hinzu:</p>{
  "split": {
    "field": "type",
    "separator": ":",
    "ignore_missing": true
  }
}<p>Die finale Datenaufnahmepipeline sollte wie folgt aussehen:</p>{
  "description": "Ingest pipeline created by text structure finder",
  "processors": [
    {
      "csv": {
        "field": "message",
        "target_fields": [
          "abbrev",
          "name",
          "scalerank",
          "type",
          "location",
          "country",
          "city",
          "city_location",
          "elevation"
        ],
        "ignore_missing": false,
        "trim": true
      }
    },
    {
      "convert": {
        "field": "scalerank",
        "type": "long",
        "ignore_missing": true
      }
    },
    {
      "convert": {
        "field": "elevation",
        "type": "double",
        "ignore_missing": true
      }
    },
    {
      "split": {
        "field": "type",
        "separator": ":",
        "ignore_missing": true
      }
    },
    {
      "remove": {
        "field": "message"
      }
    }
  ]
}<p>Beachten Sie, dass wir keinen Konvertierungsprozessor für die Felder <code>location</code> und <code>city_location</code> hinzugefügt haben. Dies liegt daran, dass der Typ <code>geo_point</code> in der Feldzuordnung das WKT- Format der Daten in diesen Feldern bereits versteht. Der Typ <code>geo_point</code> versteht eine Reihe von Formaten, darunter <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html">WKT, GeoJSON und mehr</a>. Wenn wir beispielsweise zwei Spalten in der CSV-Datei für <code>latitude</code> und <code>longitude</code> hätten, hätten wir entweder einen <code>script</code> oder einen <code>set</code> Prozessor hinzufügen müssen, um diese zu einem einzigen <code>geo_point</code> Feld zu kombinieren (z. B. <code>"set": {"field": "location", "value": "{{lat}},{{lon}}"}</code>).</p><p>Wir sind nun bereit, die Datei zu importieren. Klicken Sie auf <code>Import</code> , und die Daten werden mit den soeben definierten Mappings und der Ingest-Pipeline in den Index importiert. Sollten beim Einlesen der Daten Fehler auftreten, werden diese von Kibana hier gemeldet, sodass Sie entweder die Quelldaten oder die Einlesepipeline bearbeiten und es erneut versuchen können.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte81621425c7289c5/6a16f70f839dfaf608dcfcad/55dde2940c7aba66ce8257d15007ef797b8a5107-1440x415.png" alt="Kibana Upload - Importieren" /><p>Beachten Sie, dass eine neue Aufnahmepipeline erstellt wurde. Dies kann angezeigt werden, indem man im Kibana-Bereich <code>Stack Management</code> auf die Option <code>Ingest pipelines</code> klickt. Hier können Sie die soeben erstellte Pipeline sehen und sie bei Bedarf bearbeiten. Tatsächlich kann der Abschnitt <code>Ingest pipelines</code> zum Erstellen und Testen von Ingest-Pipelines verwendet werden, eine sehr nützliche Funktion, wenn Sie noch komplexere Ingests planen.</p><p>Wenn Sie diese Daten sofort erkunden möchten, springen Sie zu den späteren Abschnitten. Wenn Sie aber auch die Stadtgrenzen importieren möchten, lesen Sie weiter.</p><h3>Importieren der Stadtgrenzen</h3><p>Die unter <a href="https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/supporting-blog-content/geospatial-data-ingest/airports/airport_city_boundaries.csv">airport_city_boundaries.csv</a> verfügbare Datei mit den Stadtgrenzen ist etwas einfacher zu importieren als das vorherige Beispiel. Es enthält ein <code>city_boundary</code> Feld, das eine WKT-Darstellung der Stadtgrenze als <code>POLYGON</code> ist, und ein <code>city_location</code> Feld, das eine <code>geo_point</code> Darstellung des Stadtstandorts ist. Wir können diese Daten auf ähnliche Weise wie die Flughafendaten importieren, allerdings mit einigen Unterschieden:</p><ul><li><p>Wir mussten die Überschreibungseinstellung <code>Has header row</code> auswählen, da diese nicht automatisch erkannt wurde.</p></li><li><p>Wir mussten keine Felder kürzen, da die Daten bereits frei von überflüssigen Leerzeichen waren.</p></li><li><p>Wir mussten die Datenaufnahmepipeline nicht bearbeiten, da alle Datentypen entweder Zeichenketten oder räumliche Datentypen waren.</p></li><li><p>Wir mussten jedoch die Feldzuordnungen bearbeiten, um das Feld <code>city_boundary</code> auf <code>geo_shape</code> und das Feld <code>city_location</code> auf  zu setzen. <code>geo_point</code></p></li></ul><p>Unsere endgültigen Feldzuordnungen sahen wie folgt aus:</p>{
  "properties": {
    "abbrev":        { "type": "keyword" },
    "airport":       { "type": "keyword" },
    "city":          { "type": "keyword" },
    "city_boundary": { "type": "geo_shape" },
    "city_location": { "type": "geo_point" },
    "region":        { "type": "text" }
  }
}<p>Wie beim Import mit <code>airports.csv</code> zuvor, klicken Sie einfach auf <code>Import</code> , um die Daten in den Index zu importieren. Die Daten werden mit den von uns bearbeiteten Mappings und der von Kibana definierten Ingest-Pipeline importiert.</p><h3>Erkundung von Geodaten mit Entwicklerwerkzeugen</h3><p>In Kibana ist es üblich, die indizierten Daten mit dem Befehl „Discover“ zu erkunden. Wenn Sie jedoch Ihre eigene Anwendung mit ES|QL-Abfragen schreiben möchten, könnte es interessanter sein, auf die reine Elasticsearch-API zuzugreifen. Kibana verfügt über eine komfortable Konsole zum Experimentieren mit dem Schreiben von Abfragen. Dies wird als <code>Dev Tools</code> -Konsole bezeichnet und befindet sich in der Kibana-Seitenleiste. Diese Konsole kommuniziert direkt mit dem Elasticsearch-Cluster und kann zum Ausführen von Abfragen, Erstellen von Indizes und vielem mehr verwendet werden.</p><p>Versuchen Sie Folgendes:</p>POST /_query?error_trace=true&amp;format=txt
{
  "query": """
FROM airports
| EVAL distance = ST_DISTANCE(city_location, TO_GEOPOINT("POINT(12.565 55.673)"))
| WHERE distance &lt; 1000000 AND scalerank &lt; 6 AND distance &gt; 10000
| SORT distance ASC
| KEEP distance, abbrev, name, location, country, city, elevation
| LIMIT 10
  """
}<p>Dies sollte folgende Ergebnisse liefern:</p><p>Distanz</p><p>Abkürzung</p><p>Name</p><p>Ort</p><p>Land</p><p>Stadt</p><p>Elevation</p><p>273418.05776847183</p><p>SCHINKEN</p><p>Hamburg</p><p>PUNKT (10.005647830925 53.6320011640866)</p><p>Deutschland</p><p>Norderstedt</p><p>17.0</p><p>337534.653466062</p><p>TXL</p><p>Berlin-Tegel Int'l</p><p>PUNKT (13.2903090925074 52.5544287044101)</p><p>Deutschland</p><p>Hohen Neuendorf</p><p>38,0</p><p>483713.15032266214</p><p>OSL</p><p>Oslo Gardermoen</p><p>Punkt (11.0991032762581 60.1935783171386)</p><p>Norwegen</p><p>Oslo</p><p>208.0</p><p>522538.03148094116</p><p>BMA</p><p>Bromma</p><p>PUNKT (17.9456175406145 59.3555902065112)</p><p>Schweden</p><p>Stockholm</p><p>15.0</p><p>522538.03148094116</p><p>ARN</p><p>Arlanda</p><p>Punkt (17.9307299016916 59.6511203397372)</p><p>Schweden</p><p>Stockholm</p><p>38,0</p><p>624274.8274399083</p><p>DUS</p><p>Düsseldorf Int'l</p><p>PUNKT (6,76494446612174 51,2781820420774)</p><p>Deutschland</p><p>Düsseldorf</p><p>45,0</p><p>633388.6966435644</p><p>PRG</p><p>Ruzyn</p><p>PUNKT (14.2674849854076 50.1076511703671)</p><p>Tschechien</p><p>Prag</p><p>381,0</p><p>635911.1873311149</p><p>AMS</p><p>Schiphol</p><p>Punkt (4,76437693232812 52,3089323889822)</p><p>Niederlande</p><p>Hoofddorp</p><p>-3.0</p><p>670864.137958866</p><p>FRA</p><p>Frankfurt International</p><p>PUNKT (8.57182286907608 50.0506770895207)</p><p>Deutschland</p><p>Frankfurt</p><p>111,0</p><p>683239.2529970079</p><p>WAW</p><p>Okecie Int'l</p><p>Punkt (20.9727263383587 52.171026749259)</p><p>Polen</p><p>Piaseczno</p><p>111,0</p><h2>Visualisierung von Geodaten mit Kibana Maps</h2><p>Kibana Maps ist ein leistungsstarkes Werkzeug zur Visualisierung von Geodaten. Es kann verwendet werden, um Karten mit mehreren Ebenen zu erstellen, wobei jede Ebene einen anderen Datensatz darstellt. Die Daten können auf verschiedene Weise gefiltert, aggregiert und formatiert werden. In diesem Abschnitt zeigen wir Ihnen, wie Sie in Kibana Maps eine Karte mit den Daten erstellen, die wir im vorherigen Abschnitt importiert haben.</p><p>Navigieren Sie im Kibana-Menü zu <code>Analytics</code>-&gt;<code>Maps</code> , um eine neue Kartenansicht zu öffnen. Klicken Sie auf <code>Add Layer</code> und wählen Sie <code>Documents</code> aus, wählen Sie die Datenansicht <code>airports</code> und bearbeiten Sie dann den Ebenenstil, um die Markierungen mithilfe des Feldes <code>elevation</code> einzufärben, damit wir leicht erkennen können, wie hoch jeder Flughafen liegt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcc4736d88c1abc9/6a16f7102b835f7353f4afca/9e63726d7c059331e6e20e474f8abee53dc2cbb4-840x388.png" alt="Kibana Maps – Flughafen-Layer-Stil" /><p>Klicken Sie auf „Änderungen beibehalten“, um die Karte zu speichern:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8ec3cc535b5c21d8/6a16f71375879ec091fe15dc/32ad1dadb5d341a2b66662c58638b781122fc22c-2852x1528.png" alt="Kibana Maps – Flughäfen" /><p>Fügen Sie nun eine zweite Ebene hinzu und wählen Sie diesmal die Datenansicht <code>airport_city_boundaries</code> aus. Dieses Mal verwenden wir das Feld <code>city_boundary</code> , um die Ebene zu gestalten, und stellen die Füllfarbe auf ein helles Blau ein. Dadurch werden die Stadtgrenzen auf der Karte angezeigt. Achten Sie darauf, die Ebenen neu anzuordnen, damit die Flughafenmarkierungen ganz oben liegen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2932d7ff4a7206c9/6a16f7156f7f0409f09145c7/53dd65026f9a98c13f2cc4f9328a79242f0b70de-2854x1510.png" alt="Kibana Maps – Layerstil für Stadtgrenzen" /><h2>Räumliche Verknüpfungen</h2><p>ES|QL unterstützt keine <code>JOIN</code> -Befehle, aber mit dem <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-commands.html#esql-enrich"><code>ENRICH</code></a> <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-commands.html#esql-enrich">-Befehl</a> lässt sich ein Sonderfall eines Joins realisieren. Dieser Befehl funktioniert ähnlich wie ein „Left Join“ in SQL und ermöglicht es Ihnen, Ergebnisse aus einem Index mit Daten aus einem anderen Index anzureichern, basierend auf einer räumlichen Beziehung zwischen den beiden Datensätzen.</p><p>Nehmen wir beispielsweise an, wir reichern die Ergebnisse einer Tabelle mit Flughäfen um zusätzliche Informationen über die jeweilige Stadt an, indem wir die Stadtgrenze ermitteln, die den Flughafenstandort enthält, und führen dann einige statistische Auswertungen der Ergebnisse durch:</p>FROM airports
| ENRICH city_boundaries ON city_location WITH airport, region, city_boundary
| STATS
    centroid = ST_CENTROID_AGG(location),
    count = COUNT(city_location)
    BY region
| SORT count DESC
| LIMIT 10<p>Wenn Sie diese Abfrage ausführen, ohne vorher den Anreicherungsindex vorzubereiten, erhalten Sie eine Fehlermeldung wie:</p>cannot find enrich policy [city_boundaries]<p>Dies liegt daran, dass ES|QL, wie bereits erwähnt, keine echten <code>JOIN</code> -Befehle unterstützt. Ein wichtiger Grund dafür ist, dass Elasticsearch ein verteiltes System ist und Joins aufwändige Operationen sind, die schwer zu skalieren sind. Der Befehl <code>ENRICH</code> kann jedoch sehr effizient sein, da er speziell vorbereitete Anreicherungsindizes nutzt, die im gesamten Cluster dupliziert werden, wodurch lokale Joins auf jedem Knoten durchgeführt werden können.</p><p>Um dies besser zu verstehen, konzentrieren wir uns auf den Befehl <code>ENRICH</code> in der obigen Abfrage:</p>FROM airports
| ENRICH city_boundaries ON city_location WITH airport, region, city_boundary<p>Dieser Befehl weist Elasticsearch an, die aus dem Index <code>airports</code> abgerufenen Ergebnisse anzureichern und einen Join <code>intersects</code> zwischen dem Feld <code>city_location</code> des ursprünglichen Index und dem Feld <code>city_boundary</code> des Index <code>airport_city_boundaries</code> durchzuführen, den wir bereits in einigen Beispielen verwendet haben. Einige dieser Informationen sind in dieser Abfrage jedoch nicht klar ersichtlich. Was wir sehen, ist der Name einer Anreicherungsrichtlinie <code>city_boundaries</code>, und die fehlenden Informationen sind in dieser Richtliniendefinition enthalten.</p>{
  "geo_match": {
    "indices": "airport_city_boundaries",
    "match_field": "city_boundary",
    "enrich_fields": ["city", "airport", "region", "city_boundary"]
  }
}<p>Hier sehen wir, dass eine <code>geo_match</code> -Abfrage durchgeführt wird (<code>intersects</code> ist der Standardwert), das Feld, mit dem abgeglichen werden soll, ist <code>city_boundary</code>, und die <code>enrich_fields</code> sind die Felder, die wir dem Originaldokument hinzufügen möchten. Eines dieser Felder, nämlich <code>region</code> wurde tatsächlich als Gruppierungsschlüssel für den Befehl <code>STATS</code> verwendet, was ohne diese 'left join'-Funktion nicht möglich gewesen wäre. Weitere Informationen zu Anreicherungsrichtlinien finden Sie in der <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-setup.html">Anreicherungsdokumentation</a>.</p><p>Die Anreicherungsindizes und -richtlinien in Elasticsearch wurden ursprünglich für die Anreicherung von Daten während der Indexierung entwickelt, wobei Daten aus einem anderen vorbereiteten Anreicherungsindex verwendet wurden. In ES|QL hingegen funktioniert der Befehl <code>ENRICH</code> zur Abfragezeit und erfordert keine Verwendung von Ingest-Pipelines. Dadurch ähnelt es im Prinzip einem SQL <code>LEFT JOIN</code>, nur dass man nicht beliebige zwei Indizes verknüpfen kann, sondern nur einen normalen Index auf der linken Seite mit einem speziell vorbereiteten Anreicherungsindex auf der rechten Seite.</p><p>In beiden Fällen, ob für Ingest-Pipelines oder die Verwendung in ES|QL, müssen einige vorbereitende Schritte durchgeführt werden, um den Anreicherungsindex und die Richtlinie einzurichten. Wir haben den Index <code>airport_city_boundaries</code> bereits oben importiert, dieser kann jedoch nicht direkt als Anreicherungsindex im Befehl <code>ENRICH</code> verwendet werden. Zunächst müssen wir zwei Schritte durchführen:</p><ul><li><p>Erstellen Sie die oben beschriebene Anreicherungsrichtlinie, um den Quellindex, das Feld im Quellindex, mit dem abgeglichen werden soll, und die Felder, die nach dem Abgleich zurückgegeben werden sollen, zu definieren.</p></li><li><p>Führen Sie diese Richtlinie aus, um den Anreicherungsindex zu erstellen. Dabei wird ein spezieller interner Index erstellt, indem der ursprüngliche Quellindex in eine effizientere Datenstruktur eingelesen und anschließend im gesamten Cluster kopiert wird.</p></li></ul><p>Die Anreicherungsrichtlinie kann mit folgendem Befehl erstellt werden:</p>PUT /_enrich/policy/city_boundaries
{
  "match": {
    "indices": "airport_city_boundaries",
    "match_field": "city_boundary",
    "enrich_fields": ["city", "airport", "region", "city_boundary"]
  }
}<p>Die Richtlinie kann mit folgendem Befehl ausgeführt werden:</p>POST /_enrich/policy/city_boundaries/_execute<p>Beachten Sie, dass Sie diese Richtlinie erneut ausführen müssen, wenn Sie den Inhalt des Index <code>airport_city_boundaries</code> ändern, damit die Änderungen im Anreicherungsindex sichtbar werden. Führen wir nun die ursprüngliche ES|QL-Abfrage erneut aus:</p>FROM airports
| ENRICH city_boundaries ON city_location WITH airport, region, city_boundary
| STATS
    centroid = ST_CENTROID_AGG(location),
    count = COUNT(city_location)
    BY region
| SORT count DESC
| LIMIT 10<p>Dies liefert die Top 5 Regionen mit den meisten Flughäfen, zusammen mit dem Schwerpunkt aller Flughäfen, die übereinstimmenden Regionen zugeordnet sind, und der Längenspanne der WKT-Darstellung der Stadtgrenzen innerhalb dieser Regionen:</p><p>Schwerpunkt</p><p>Anzahl</p><p>Region</p><p>PUNKT (-12.139086859300733 31.024386116624648)</p><p>126</p><p>null</p><p>PUNKT (-83.10398317873478 42.300230911932886)</p><p>3</p><p>Detroit</p><p>Punkt (39.74537850357592 47.21613017376512)</p><p>3</p><p>городской округ Батайск</p><p>PUNKT (-156.80986787192523 20,476673701778054)</p><p>3</p><p>Hawaii</p><p>PUNKT (-73.94515332765877 40.70366442203522)</p><p>3</p><p>Stadt New York</p><p>PUNKT (-83.10398317873478 42.300230911932886)</p><p>3</p><p>Detroit</p><p>PUNKT (-76.66873019188643 24.306286952923983)</p><p>2</p><p>New Providence</p><p>PUNKT (-3,0252167768776417 51,39245774131268)</p><p>2</p><p>Cardiff</p><p>PUNKT (-115.40993484668434 32,73126147687435)</p><p>2</p><p>Municipio de Mexicali</p><p>Punkt (41.790108773857355 50.302146775648)</p><p>2</p><p>Zentralbezirk</p><p>PUNKT (-73.88902732171118 45.57078813901171)</p><p>2</p><p>Montréal</p><p>Möglicherweise stellen Sie auch fest, dass die am häufigsten vorkommende Region <code>null</code> war. Was könnte das bedeuten? Zur Erinnerung: Ich habe diesen Befehl mit einem 'Left Join' in SQL verglichen. Das bedeutet, dass, wenn keine übereinstimmende Stadtgrenze für einen Flughafen gefunden wird, der Flughafen trotzdem zurückgegeben wird, jedoch mit <code>null</code> Werten für die Felder ab dem <code>airport_city_boundaries</code> Index. Es stellte sich heraus, dass es 125 Flughäfen gab, bei denen kein passender Eintrag <code>city_boundary</code> gefunden wurde, und einen Flughafen mit einer Übereinstimmung, bei dem das Feld <code>region</code> den <code>null</code> hatte. Dies führte zu einer Zählung von 126 Flughäfen ohne <code>region</code> in den Ergebnissen. Falls Ihr Anwendungsfall erfordert, dass alle Flughäfen einer Stadtgrenze zugeordnet werden können, müssten zusätzliche Daten beschafft werden, um die Lücken zu schließen. Es wäre notwendig, zwei Dinge zu ermitteln:</p><ul><li><p>Welche Datensätze im Index <code>airport_city_boundaries</code> haben keine <code>city_boundary</code> Felder?</p></li><li><p>welche Datensätze im Index <code>airports</code> nicht mit dem Befehl <code>ENRICH</code> übereinstimmen (d.h. (überschneiden sich nicht)</p></li></ul><h2>Verwendung von ES|QL für Geodaten in Kibana Maps</h2><p>Kibana hat die Unterstützung für Spatial ES|QL in der Kartenanwendung hinzugefügt. Das bedeutet, dass Sie nun ES|QL verwenden können, um in Elasticsearch nach Geodaten zu suchen und die Ergebnisse auf einer Karte zu visualisieren.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt91922eb4ef43d290/6a16f7161949f737bfe7a7b5/bd78470bd8a4bc60f0db7006bd804b8fe87e2fea-1440x683.png" alt="Kibana Layers ES|QL" /><p>Im Menü „Ebenen hinzufügen“ gibt es eine neue Ebenenoption mit der Bezeichnung „ES|QL“. Wie alle bisher beschriebenen Geodatenfunktionen befindet sich auch diese in der „technischen Vorschauphase“. Durch Auswahl dieser Option können Sie der Karte eine Ebene hinzufügen, die auf den Ergebnissen einer ES|QL-Abfrage basiert. Man könnte beispielsweise eine Ebene zur Karte hinzufügen, die alle Flughäfen der Welt anzeigt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5185ef7461d7e81d/6a16f718839dfa1559dcfcb1/1dd28d3d0509f92d26b0bb5320a2925f7a54c5d9-1440x736.png" alt="Kibana ES|QL - Flughäfen" /><p>Oder Sie könnten eine Ebene hinzufügen, die die Polygone ab dem Index <code>airport_city_boundaries</code> anzeigt, oder noch besser, wie wäre es mit der komplexen <code>ENRICH</code> -Abfrage oben, die Statistiken darüber generiert, wie viele Flughäfen sich in jeder Region befinden?</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt51ee3543bb811d98/6a16f71a8b73cbbe63189df1/679a0a401faa613c7cedddd07c64f614ac2b7144-1440x727.png" alt="Kibana ES|QL – Regionsstatistik" /><h2>Was kommt als Nächstes?</h2><p>Der vorherige Blogbeitrag <a href="https://www.elastic.co/search-labs/blog/esql-geospatial-search-part-one">zum Thema Geodaten-Suche</a> konzentrierte sich auf die Verwendung von Funktionen wie <code>ST_INTERSECTS</code> zur Durchführung von Suchvorgängen, die in Elasticsearch seit Version 8.14 verfügbar sind. Und in diesem Blog erfahren Sie, wie Sie die Daten importieren können, die wir für diese Suchvorgänge verwendet haben. Elasticsearch 8.15 brachte jedoch eine besonders interessante Funktion mit sich: <code>ST_DISTANCE</code> , mit der sich effiziente räumliche Distanzsuchen durchführen lassen, und dies wird das Thema des nächsten Blogbeitrags sein!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/geospatial-data-ingest-for-esql</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/geospatial-data-ingest-for-esql</guid>
    <category><![CDATA[Kibana]]></category>
    <category><![CDATA[ES|QL]]></category>
    <dc:creator><![CDATA[Craig Taverner]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc041ebca11476c6/6a16f70560084b31b93c4344/01fde3b1d714f12bf8673140c9f2f940d443de31-1440x823.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 25 Oct 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Geodaten-Suche mit Elasticsearch und ES|QL]]></title>
    <description><![CDATA[Geodaten-Suche in der Elasticsearch Query Language (ES|QL). Elasticsearch verfügt über leistungsstarke Geodaten-Suchfunktionen, die nun in ES|QL integriert werden, um die Benutzerfreundlichkeit und OGC-Vertrautheit deutlich zu verbessern.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch verfügt seit vielen Jahren über leistungsstarke <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/geospatial-analysis.html">Funktionen für die Geodaten-Suche und -Analyse</a> , aber die API unterschied sich deutlich von dem, was typische GIS-Anwender gewohnt waren. Im vergangenen Jahr haben wir <a href="https://www.elastic.co/search-labs/blog/esql-piped-query-language-goes-ga">die Abfragesprache ES|QL hinzugefügt</a>, eine Pipe-Abfragesprache, die genauso einfach oder sogar noch einfacher als SQL ist. Es eignet sich besonders für die Anwendungsfälle Suche, Sicherheit und Beobachtbarkeit, in denen Elastic hervorragende Leistungen erbringt. Wir fügen außerdem Unterstützung für die Geodaten-Suche und -Analyse innerhalb von ES|QL hinzu, was die Nutzung deutlich vereinfacht, insbesondere für Anwender aus SQL- oder <a href="https://en.wikipedia.org/wiki/Geographic_information_system">GIS-</a> Bereichen.</p><p>Elasticsearch 8.12 und 8.13 führten die grundlegende Unterstützung für Geodaten-Typen in ES|QL ein. Dies wurde durch die Hinzufügung von Geodaten-Suchfunktionen in Version 8.14 deutlich verbessert. Wichtiger noch: Diese Unterstützung wurde so konzipiert, dass sie sich eng an den <a href="https://en.wikipedia.org/wiki/Simple_Features">Simple Feature Access-</a> Standard des <a href="https://en.wikipedia.org/wiki/Open_Geospatial_Consortium">Open Geospatial Consortium (OGC)</a> anlehnt, der auch von anderen räumlichen Datenbanken wie PostGIS verwendet wird. Dadurch wird die Nutzung für GIS-Experten, die mit diesen Standards vertraut sind, deutlich vereinfacht.</p><p>In diesem Blog zeigen wir Ihnen, wie Sie mit ES|QL Geodatenabfragen durchführen und wie sich dies im Vergleich zu den entsprechenden SQL- und Query-DSL-Funktionen verhält. Wir zeigen Ihnen außerdem, wie Sie mit ES|QL räumliche Verknüpfungen durchführen und wie Sie die Ergebnisse in Kibana Maps visualisieren. Bitte beachten Sie, dass sich alle hier beschriebenen Funktionen in der „technischen Vorschau“ befinden. Wir freuen uns über Ihr Feedback, wie wir diese verbessern können.</p><h2>Suche nach Geodaten</h2><p>Beginnen wir mit einer Beispielabfrage:</p>FROM airport_city_boundaries
| WHERE ST_INTERSECTS(
      city_boundary,
      "POLYGON((109.4 18.1, 109.6 18.1, 109.6 18.3, 109.4 18.3, 109.4 18.1))"::geo_shape
  )
| KEEP abbrev, airport, region, city, city_location
<p>Hierbei wird nach Stadtgrenzenpolygonen gesucht, die sich mit einem rechteckigen Suchpolygon um den internationalen Flughafen Sanya Phoenix (SYX) schneiden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3897df6bed5d6061/6a17d7c2abe0f29eccdfe861/e48bac8f246c8842f2ea97ddd54910045262aeb1-1440x808.png" alt="ESQL-Geodatensuche" /><p>In einem Beispieldatensatz mit Flughäfen, Städten und Stadtgrenzen findet diese Suche das sich überschneidende Polygon und gibt die gewünschten Felder aus dem übereinstimmenden Dokument zurück:</p><p>Abkürzung</p><p>Flughafen</p><p>Region</p><p>Stadt</p><p>Stadtstandort</p><p>SYX</p><p>Sanya Phoenix Int'l</p><p>天涯区</p><p>Sanya</p><p>Punkt(109.5036 18.2533)</p><p>Das war einfach! Vergleichen Sie dies nun mit der klassischen Elasticsearch Query DSL für dieselbe Abfrage:</p>GET /airport_city_boundaries/_search
{
  "_source": ["abbrev", "airport", "region", "city", "city_location"],
  "query": {
    "geo_shape": {
      "city_boundary": {
        "shape": {
          "type": "polygon",
          "coordinates" : [[
            [109.4, 18.1],
            [109.6, 18.1],
            [109.6, 18.3],
            [109.4, 18.3],
            [109.4, 18.1]
          ]]
        }
      }
    }
  }
}
<p>Beide Abfragen sind in ihrer Absicht einigermaßen klar, aber die ES|QL-Abfrage ähnelt stark SQL. Die gleiche Abfrage in PostGIS sieht folgendermaßen aus:</p>SELECT abbrev, airport, region, city, city_location
FROM airport_city_boundaries
WHERE ST_INTERSECTS(
    city_boundary,
    'SRID=4326;POLYGON((109.4 18.1, 109.6 18.1, 109.6 18.3, 109.4 18.3, 109.4 18.1))'::geometry
);
<p>Schauen Sie sich das ES|QL-Beispiel noch einmal an. So ähnlich, nicht wahr?</p>FROM airport_city_boundaries
| WHERE ST_INTERSECTS(
      city_boundary,
      "POLYGON((109.4 18.1, 109.6 18.1, 109.6 18.3, 109.4 18.3, 109.4 18.1))"::geo_shape
  )
| KEEP abbrev, airport, region, city, city_location
<p>Wir haben festgestellt, dass bestehende Benutzer der Elasticsearch API ES|QL als wesentlich einfacher zu bedienen empfinden. Wir gehen davon aus, dass bestehende SQL-Anwender, insbesondere Spatial SQL-Anwender, feststellen werden, dass sich ES|QL sehr vertraut anfühlt und ihnen sehr ähnlich ist.</p><h4>Warum nicht SQL?</h4><p>Und wie sieht es mit Elasticsearch SQL aus? Es existiert schon eine Weile und verfügt über einige Geodatenfunktionen. Elasticsearch SQL wurde jedoch als Wrapper für die ursprüngliche Query-API geschrieben, was bedeutete, dass nur Abfragen unterstützt wurden, die in die ursprüngliche API transpiliert werden konnten. ES|QL hat diese Einschränkung nicht. Da es sich um einen völlig neuen Stack handelt, sind viele Optimierungen möglich, die in SQL nicht möglich waren. Unsere Benchmarks zeigen, dass ES|QL <a href="https://elasticsearch-benchmarks.elastic.co/#tracks/esql/nightly/default/6M">sehr oft schneller ist als die Query API</a>, insbesondere bei Aggregationen!</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18bda964c8b24e36/6a17d7c3e3179155d22d568a/b8b6c2b2e45850d832805ed1e71e522f4955f53c-1440x813.png" alt="Polygon-Schnittpunkt-Benchmark" /><h2>Unterschiede zu SQL</h2><p>Wie das vorherige Beispiel zeigt, ist ES|QL SQL zwar in gewisser Weise ähnlich, es gibt aber auch einige wichtige Unterschiede. ES|QL ist beispielsweise eine Pipe-Abfragesprache, die mit einem Quellbefehl wie FROM beginnt und dann alle nachfolgenden Befehle mit dem Pipe-Zeichen | miteinander verkettet. Dadurch wird es sehr einfach verständlich, wie jeder Befehl eine Datentabelle empfängt und eine bestimmte Aktion an dieser Tabelle durchführt, z. B. Filtern mit <code>WHERE</code>, Hinzufügen von Spalten mit <code>EVAL</code> oder Durchführen von Aggregationen mit <code>STATS</code>. Anstatt mit <code>SELECT</code> zu beginnen, um die endgültigen Ausgabespalten zu definieren, können ein oder mehrere <code>KEEP</code> -Befehle verwendet werden, wobei der letzte Befehl die endgültigen Ausgaberesultate angibt. Diese Struktur vereinfacht die Argumentation bezüglich der Anfrage.</p><p>Wenn wir uns den Befehl <code>WHERE</code> im obigen Beispiel genauer ansehen, erkennen wir, dass er dem PostGIS-Beispiel sehr ähnlich sieht:</p><p><em>ES|QL</em></p>WHERE ST_INTERSECTS(
    city_boundary,
    "POLYGON((109.4 18.1, 109.6 18.1, 109.6 18.3, 109.4 18.3, 109.4 18.1))"::geo_shape
)
<p><em>PostGIS</em></p>WHERE ST_INTERSECTS(
    city_boundary,
    'SRID=4326;POLYGON((109.4 18.1, 109.6 18.1, 109.6 18.3, 109.4 18.3, 109.4 18.1))'::geometry
)
<p>Abgesehen von den Unterschieden bei den Anführungszeichen für Zeichenketten besteht der größte Unterschied darin, wie wir die Zeichenkette in einen räumlichen Datentyp umwandeln. In PostGIS verwenden wir das Suffix <code>::geometry</code> , während wir in ES|QL das Suffix <code>::geo_shape</code> verwenden. Dies liegt daran, dass ES|QL innerhalb von Elasticsearch ausgeführt wird und der Typumwandlungsoperator <code>::</code> verwendet werden kann, um eine Zeichenkette in einen der <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-limitations.html#_supported_types">unterstützten ES|QL-Typen</a> umzuwandeln, in diesem Fall in einen <code>geo_shape</code>. Darüber hinaus implizieren die Typen <code>geo_shape</code> und <code>geo_point</code> in Elasticsearch das räumliche Koordinatensystem WGS84, das häufiger unter der SRID-Nummer 4326 bezeichnet wird. In PostGIS muss dies explizit angegeben werden, daher die Verwendung des Präfixes <code>SRID=4326;</code> für die WKT-Zeichenkette. Wird dieses Präfix entfernt, wird die SRID auf 0 gesetzt, was eher den Elasticsearch-Typen <code>cartesian_point</code> und <code>cartesian_shape</code> entspricht, die nicht an ein bestimmtes Koordinatensystem gebunden sind.</p><p>Sowohl ES|QL als auch PostGIS bieten eine Syntax für Typkonvertierungsfunktionen:</p><p><em>ES|QL</em></p>WHERE ST_INTERSECTS(
    city_boundary,
    TO_GEOSHAPE("POLYGON((109.4 18.1, 109.6 18.1, 109.6 18.3, 109.4 18.3, 109.4 18.1))")
)
<p><em>PostGIS</em></p>WHERE ST_INTERSECTS(
    city_boundary,
    ST_SetSRID(
      ST_GeomFromText('POLYGON((109.4 18.1, 109.6 18.1, 109.6 18.3, 109.4 18.3, 109.4 18.1))'),
      4326
    )
)
<h2>OGC-Funktionen</h2><p>Elasticsearch 8.14 führt die folgenden vier OGC-Funktionen für die räumliche Suche ein:</p><p>ES|QL</p><p>PostGIS</p><p>Beschreibung</p><p>ST_INTERSECTS</p><p>ST_Schnittpunkte</p><p>Gibt true zurück, wenn sich zwei Geometrien schneiden, und andernfalls false.</p><p>ST_DISJOINT</p><p>ST_Disjoint</p><p>Gibt true zurück, wenn sich zwei Geometrien nicht schneiden, und andernfalls false. Die Umkehrfunktion von ST_INTERSECTS.</p><p>ST_CONTAINS</p><p>ST_Contains</p><p>Gibt true zurück, wenn eine Geometrie eine andere enthält, andernfalls false.</p><p>ST_WITHIN</p><p>ST_Within</p><p>Gibt true zurück, wenn sich eine Geometrie innerhalb einer anderen befindet, und andernfalls false. Das Inverse von ST_CONTAINS.</p><p>Diese Funktionen verhalten sich ähnlich wie ihre PostGIS-Pendants und werden auf die gleiche Weise verwendet. Beispielsweise gibt <code>ST_INTERSECTS</code> true zurück, wenn sich zwei Geometrien schneiden, und andernfalls false. Wenn Sie den Dokumentationslinks in der obigen Tabelle folgen, werden Sie feststellen, dass sich alle ES|QL-Beispiele innerhalb einer <code>WHERE</code> -Klausel nach einer <code>FROM</code> -Klausel befinden, während alle PostGIS-Beispiele literale Geometrien verwenden. Tatsächlich unterstützen beide Plattformen die Verwendung der Funktionen in jedem Teil der Abfrage, in dem sie sinnvoll sind.</p><p>Das erste Beispiel in der PostGIS-Dokumentation für <code>ST_INTERSECTS</code> lautet:</p>SELECT ST_Intersects(
    'POINT(0 0)'::geometry,
    'LINESTRING ( 2 0, 0 2 )'::geometry
);
<p>Das ES|QL-Äquivalent dazu wäre:</p>ROW ST_INTERSECTS(
    "POINT(0 0)"::geo_point,
    "LINESTRING ( 2 0, 0 2 )"::geo_shape
)
<p>Beachten Sie, dass wir im PostGIS-Beispiel die SRID nicht angegeben haben. Dies liegt daran, dass in PostGIS bei Verwendung des Typs <code>geometry</code> alle Berechnungen auf einem planaren Koordinatensystem durchgeführt werden. Wenn also beide Geometrien die gleiche SRID haben, spielt es keine Rolle, welche SRID es ist. In Elasticsearch gilt dies auch für die meisten Funktionen. Es gibt jedoch Ausnahmen, bei denen <code>geo_shape</code> und <code>geo_point</code> sphärische Berechnungen verwenden, wie wir im nächsten Blogbeitrag über die Suche nach räumlichen Distanzen sehen werden.</p><h2>ES|QL Vielseitigkeit</h2><p>Wir haben oben also Beispiele für die Verwendung von räumlichen Funktionen in <code>WHERE</code> -Klauseln und in <code>ROW</code> -Befehlen gesehen. Wo sonst würden sie Sinn machen? Eine sehr nützliche Stelle dafür ist der Befehl <code>EVAL</code> . Mit diesem Befehl können Sie einen Ausdruck auswerten und das Ergebnis zurückgeben. Nehmen wir beispielsweise an, wir wollen feststellen, ob die Schwerpunkte aller Flughäfen, gruppiert nach ihren Ländernamen, innerhalb einer Grenze liegen, die das jeweilige Land umschließt:</p>FROM airports
| EVAL in_uk = ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))"))
| EVAL in_iceland = ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON ((-25.4883 65.5312, -23.4668 66.7746, -18.4131 67.4749, -13.0957 66.2669, -12.3926 64.4159, -20.1270 62.7346, -24.7852 63.3718, -25.4883 65.5312))"))
| EVAL within_uk = ST_WITHIN(location, TO_GEOSHAPE("POLYGON((1.2305 60.8449, -1.582 61.6899, -10.7227 58.4017, -7.1191 55.3291, -7.9102 54.2139, -5.4492 54.0078, -5.2734 52.3756, -7.8223 49.6676, -5.0977 49.2678, 0.9668 50.5134, 2.5488 52.1065, 2.6367 54.0078, -0.9668 56.4625, 1.2305 60.8449))"))
| EVAL within_iceland = ST_WITHIN(location, TO_GEOSHAPE("POLYGON ((-25.4883 65.5312, -23.4668 66.7746, -18.4131 67.4749, -13.0957 66.2669, -12.3926 64.4159, -20.1270 62.7346, -24.7852 63.3718, -25.4883 65.5312))"))
| STATS centroid = ST_CENTROID_AGG(location), count=COUNT() BY in_uk, in_iceland, within_uk, within_iceland
| SORT count ASC
<p>Die Ergebnisse sind erwartungsgemäß: Die Schwerpunkte der britischen Flughäfen liegen innerhalb der Grenzen Großbritanniens und nicht innerhalb der Grenzen Islands, und umgekehrt.</p><p>Schwerpunkt</p><p>Anzahl</p><p>in_uk</p><p>in Island</p><p>innerhalb Großbritanniens</p><p>innerhalb Islands</p><p>PUNKT (-21,946634463965893 64.13187285885215)</p><p>1</p><p>FALSCH</p><p>wahr</p><p>FALSCH</p><p>wahr</p><p>PUNKT (-2,597342072712148 54,33551226578214)</p><p>17</p><p>wahr</p><p>FALSCH</p><p>wahr</p><p>FALSCH</p><p>PUNKT (0,04453958108176276 23,74658354606057)</p><p>873</p><p>FALSCH</p><p>FALSCH</p><p>FALSCH</p><p>FALSCH</p><p>Tatsächlich können diese Funktionen in jedem Teil der Abfrage verwendet werden, in dem ihre Signatur sinnvoll ist. Sie alle nehmen zwei Argumente entgegen, die entweder ein Literal eines räumlichen Objekts oder ein Feld eines räumlichen Typs sind, und sie alle geben einen booleschen Wert zurück. Eine wichtige Überlegung ist, dass das Koordinatenreferenzsystem (CRS) der Geometrien übereinstimmen muss, andernfalls wird ein Fehler zurückgegeben. Das bedeutet, dass Sie die Typen <code>geo_shape</code> und <code>cartesian_shape</code> nicht im selben Funktionsaufruf mischen können. Allerdings können Sie die Typen <code>geo_point</code> und <code>geo_shape</code> mischen, da der Typ <code>geo_point</code> ein Sonderfall des Typs <code>geo_shape</code> ist und beide das gleiche Koordinatenreferenzsystem verwenden. Die Dokumentation zu jeder der oben definierten Funktionen listet die unterstützten Typkombinationen auf.</p><p>Darüber hinaus kann jedes Argument ein räumliches Literal oder ein Feld sein, in beliebiger Reihenfolge. Sie können sogar zwei Felder, zwei Literale, ein Feld und ein Literal oder ein Literal und ein Feld angeben. Die einzige Voraussetzung ist, dass die Datentypen kompatibel sind. Diese Abfrage vergleicht beispielsweise zwei Felder im selben Index:</p>FROM airport_city_boundaries
| EVAL in_city = ST_INTERSECTS(city_location, city_boundary)
| STATS count=COUNT(*) BY in_city
| SORT count ASC
| EVAL cardinality = CASE(count &lt; 10, "very few", count &lt; 100, "few", "many")
| KEEP cardinality, count, in_city
<p>Die Anfrage zielt im Grunde darauf ab, ob sich der Ort innerhalb der Stadtgrenzen befindet, was im Allgemeinen zutreffen sollte, aber es gibt immer Ausnahmen:</p><p>Kardinalität</p><p>Anzahl</p><p>in_city</p><p>wenige</p><p>29</p><p>FALSCH</p><p>viele</p><p>740</p><p>wahr</p><p>Eine weitaus interessantere Frage wäre, ob sich der Flughafenstandort innerhalb der Grenzen der Stadt befindet, die der Flughafen bedient. Der Standort des Flughafens befindet sich jedoch in einem anderen Index als derjenige, der die Stadtgrenzen enthält. Dies erfordert eine Methode, um Daten aus diesen beiden separaten Indizes effektiv abzufragen und zu korrelieren.</p><h2>Räumliche Verknüpfungen</h2><p>ES|QL unterstützt keine <code>JOIN</code> -Befehle, aber Sie können einen Sonderfall eines Joins mit dem <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-commands.html#esql-enrich"><code>ENRICH</code></a><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-commands.html#esql-enrich"> -Befehl</a> erreichen, der sich ähnlich wie ein 'left join' in SQL verhält. Dieser Befehl funktioniert ähnlich wie ein „Left Join“ in SQL und ermöglicht es Ihnen, Ergebnisse aus einem Index mit Daten aus einem anderen Index anzureichern, basierend auf einer räumlichen Beziehung zwischen den beiden Datensätzen.</p><p>Nehmen wir beispielsweise an, wir reichern die Ergebnisse einer Tabelle mit Flughäfen um zusätzliche Informationen über die jeweilige Stadt an, indem wir die Stadtgrenze ermitteln, die den Flughafenstandort enthält, und führen dann einige statistische Auswertungen der Ergebnisse durch:</p>FROM airports
| ENRICH city_boundaries ON city_location WITH airport, region, city_boundary
| MV_EXPAND city_boundary
| EVAL boundary_wkt_length = LENGTH(TO_STRING(city_boundary))
| STATS centroid = ST_CENTROID_AGG(location), count = COUNT(city_location), min_wkt = MIN(boundary_wkt_length), max_wkt = MAX(boundary_wkt_length) BY region
| SORT count DESC
| LIMIT 5
<p>Dies liefert die Top 5 Regionen mit den meisten Flughäfen, zusammen mit dem Schwerpunkt aller Flughäfen, die übereinstimmenden Regionen zugeordnet sind, und der Längenspanne der WKT-Darstellung der Stadtgrenzen innerhalb dieser Regionen:</p><p>Schwerpunkt</p><p>Anzahl</p><p>min_wkt</p><p>max_wkt</p><p>Region</p><p>PUNKT (-32.56093470960719 32.598117914802714)</p><p>90</p><p>207</p><p>207</p><p>null</p><p>PUNKT (-73.94515332765877 40.70366442203522)</p><p>9</p><p>438</p><p>438</p><p>Stadt New York</p><p>PUNKT (-83.10398317873478 42.300230911932886)</p><p>9</p><p>473</p><p>473</p><p>Detroit</p><p>PUNKT (-156.3020245861262 20.176383580081165)</p><p>5</p><p>307</p><p>803</p><p>Hawaii</p><p>PUNKT (-73.88902732171118 45.57078813901171)</p><p>4</p><p>837</p><p>837</p><p>Montréal</p><p>Was ist hier also wirklich geschehen? Wo trat das vermeintliche <code>JOIN</code> auf? Der Kern der Anfrage liegt im Befehl <code>ENRICH</code> :</p>FROM airports
| ENRICH city_boundaries ON city_location WITH airport, region, city_boundary
<p>Dieser Befehl weist Elasticsearch an, die aus dem Index <code>airports</code> abgerufenen Ergebnisse anzureichern und einen Join <code>intersects</code> zwischen dem Feld <code>city_location</code> des ursprünglichen Index und dem Feld <code>city_boundary</code> des Index <code>airport_city_boundaries</code> durchzuführen, den wir bereits in einigen Beispielen verwendet haben. Einige dieser Informationen sind in dieser Abfrage jedoch nicht klar ersichtlich. Was wir sehen, ist der Name einer Anreicherungsrichtlinie <code>city_boundaries</code>, und die fehlenden Informationen sind in dieser Richtliniendefinition enthalten.</p>{
  "geo_match": {
    "indices": "airport_city_boundaries",
    "match_field": "city_boundary",
    "enrich_fields": ["city", "airport", "region", "city_boundary"]
  }
}
<p>Hier sehen wir, dass eine <code>geo_match</code> -Abfrage durchgeführt wird (<code>intersects</code> ist der Standardwert), das Feld, mit dem abgeglichen werden soll, ist <code>city_boundary</code>, und die <code>enrich_fields</code> sind die Felder, die wir dem Originaldokument hinzufügen möchten. Eines dieser Felder, nämlich <code>region</code> wurde tatsächlich als Gruppierungsschlüssel für den Befehl <code>STATS</code> verwendet, was ohne diese 'left join'-Funktion nicht möglich gewesen wäre. Weitere Informationen zu Anreicherungsrichtlinien finden Sie in der <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-setup.html">Anreicherungsdokumentation</a>. Beim Lesen dieser Dokumente werden Sie feststellen, dass darin die Verwendung von Anreicherungsindizes zur Anreicherung von Daten während der Indexierung durch die Konfiguration von Aufnahmepipelines beschrieben wird. Dies ist für ES|QL nicht erforderlich, da der Befehl <code>ENRICH</code> zur Abfragezeit funktioniert. Es genügt, den Anreicherungsindex mit den erforderlichen Daten und der Anreicherungsrichtlinie vorzubereiten und dann den Befehl <code>ENRICH</code> in Ihren ES|QL-Abfragen zu verwenden.</p><p>Möglicherweise stellen Sie auch fest, dass die am häufigsten vorkommende Region <code>null</code> war. Was könnte das bedeuten? Zur Erinnerung: Ich habe diesen Befehl mit einem 'Left Join' in SQL verglichen. Das bedeutet, dass, wenn keine übereinstimmende Stadtgrenze für einen Flughafen gefunden wird, der Flughafen trotzdem zurückgegeben wird, jedoch mit <code>null</code> Werten für die Felder ab dem <code>airport_city_boundaries</code> Index. Es stellte sich heraus, dass es 89 Flughäfen gab, bei denen kein passender Eintrag <code>city_boundary</code> gefunden wurde, und einen Flughafen mit einer Übereinstimmung, bei dem das Feld <code>region</code> den <code>null</code> hatte. Dies führte zu einer Zählung von 90 Flughäfen, bei denen keine <code>region</code> in den Ergebnissen vorkam. Ein weiteres interessantes Detail ist die Notwendigkeit des Befehls <code>MV_EXPAND</code> . Dies ist notwendig, da der Befehl <code>ENRICH</code> für jede Eingabezeile mehrere Ergebnisse zurückgeben kann, und <code>MV_EXPAND</code> hilft dabei, diese Ergebnisse in mehrere Zeilen aufzuteilen, eine für jedes Ergebnis. Dies erklärt auch, warum für "Hawaii" unterschiedliche <code>min_wkt</code> und <code>max_wkt</code> Ergebnisse angezeigt werden: Es gab mehrere Regionen mit dem gleichen Namen, aber unterschiedlichen Grenzen.</p><h2>Kibana-Karten</h2><p>Kibana hat die Unterstützung für Spatial ES|QL in der Kartenanwendung hinzugefügt. Das bedeutet, dass Sie nun ES|QL verwenden können, um in Elasticsearch nach Geodaten zu suchen und die Ergebnisse auf einer Karte zu visualisieren.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt91922eb4ef43d290/6a16f7161949f737bfe7a7b5/bd78470bd8a4bc60f0db7006bd804b8fe87e2fea-1440x683.png" alt="Kibana Layers ES|QL" /><p>Im Menü „Ebenen hinzufügen“ gibt es eine neue Ebenenoption mit der Bezeichnung „ES|QL“. Wie alle bisher beschriebenen Geodatenfunktionen befindet sich auch diese in der „technischen Vorschauphase“. Durch Auswahl dieser Option können Sie der Karte eine Ebene hinzufügen, die auf den Ergebnissen einer ES|QL-Abfrage basiert. Man könnte beispielsweise eine Ebene zur Karte hinzufügen, die alle Flughäfen der Welt anzeigt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5185ef7461d7e81d/6a16f718839dfa1559dcfcb1/1dd28d3d0509f92d26b0bb5320a2925f7a54c5d9-1440x736.png" alt="Kibana ES|QL - Flughäfen" /><p>Oder Sie könnten eine Ebene hinzufügen, die die Polygone ab dem Index <code>airport_city_boundaries</code> anzeigt, oder noch besser, wie wäre es mit der komplexen <code>ENRICH</code> -Abfrage oben, die Statistiken darüber generiert, wie viele Flughäfen sich in jeder Region befinden?</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt51ee3543bb811d98/6a16f71a8b73cbbe63189df1/679a0a401faa613c7cedddd07c64f614ac2b7144-1440x727.png" alt="Kibana ES|QL – Regionsstatistik" /><h2>Was kommt als Nächstes?</h2><p>Vielleicht ist Ihnen aufgefallen, dass wir in zwei der obigen Beispiele noch eine weitere räumliche Funktion <code>ST_CENTROID_AGG</code> eingefügt haben. Dies ist eine Aggregationsfunktion, die im Befehl <code>STATS</code> verwendet wird, und die erste von vielen räumlichen Analysefunktionen, die wir ES|QL hinzufügen wollen. Wir werden darüber bloggen, sobald wir mehr zu zeigen haben!</p><p>Zuvor möchten wir Ihnen jedoch ein besonders spannendes Feature vorstellen, an dem wir gearbeitet haben: die Möglichkeit, räumliche Distanzsuchen durchzuführen – eine der am häufigsten genutzten räumlichen Suchfunktionen von Elasticsearch. Können Sie sich vorstellen, wie die Syntax für Distanzsuchen aussehen könnte? Vielleicht ähnlich einer OGC-Funktion? Bleiben Sie dran für den nächsten Blogbeitrag dieser Reihe, um es herauszufinden!</p><p>Spoiler-Alarm: Elasticsearch 8.15 wurde soeben veröffentlicht und beinhaltet die räumliche Distanzsuche mit ES|QL!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/esql-geospatial-search-part-one</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/esql-geospatial-search-part-one</guid>
    <category><![CDATA[Python]]></category>
    <category><![CDATA[ES|QL]]></category>
    <dc:creator><![CDATA[Craig Taverner]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd05627be20e89dfb/6a17d7c6414c640256944fdb/de886289dcb56494920875303b622b030b9b810f-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 12 Aug 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Von ES|QL zu PHP-Objekten]]></title>
    <description><![CDATA[Lernen Sie, wie Sie ES|QL-Abfragen in PHP ausführen und verwalten. Folgen Sie dieser Anleitung, um ES|QL-Ergebnisse einem PHP-Objekt oder einer benutzerdefinierten Klasse zuzuordnen.]]></description>
    <content:encoded><![CDATA[<p>Ab elasticsearch-php <a href="https://github.com/elastic/elasticsearch-php/releases/tag/v8.13.0">v8.13.0</a> können Sie <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html">ES|QL-</a> Abfragen ausführen und das Ergebnis einem PHP-Objekt vom Typ <a href="https://www.php.net/manual/en/class.stdclass.php">stdClass</a> oder einer benutzerdefinierten Klasse zuordnen.</p><h2>ES|QL</h2><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html">ES|QL</a> ist eine neue Elasticsearch-Abfragesprache, die in Elasticsearch 8.11.0 eingeführt wurde. Aktuell ist es als technische Vorschau verfügbar. Es bietet eine leistungsstarke Möglichkeit, in Elasticsearch gespeicherte Daten zu filtern, zu transformieren und zu analysieren.</p><p>Es verwendet "Pipes" (<code>|</code>), um Daten schrittweise zu manipulieren und zu transformieren. Dieser Ansatz ermöglicht es den Benutzern, eine Reihe von Operationen zu erstellen, wobei das Ergebnis einer Operation als Eingabe für die nächste dient, wodurch komplexe Datentransformationen und -analysen möglich werden.</p><p>Die folgende Abfrage gibt beispielsweise die ersten 3 Dokumente (Zeilen) des Index <code>sample_data</code> zurück:</p>FROM sample_data
| LIMIT 3
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8b0310cb335872b7/6a17d7eab1e113258679f0df/c23aee777bacdf90c63b717fd9458207dfc0511d-864x284.png" alt="ES|QL erzeugt Tabellen" /><h2>Anwendungsfall: ES|QL-Funktionen im offiziellen PHP-Client</h2><p>Um die im offiziellen PHP-Client entwickelten ES|QL-Funktionen zu veranschaulichen, haben wir eine <a href="https://github.com/elastic/elasticsearch-php-examples/blob/main/examples/ESQL/data/books.csv">CSV-Datei</a> mit 81.828 Büchern (54,4 MB) in Elasticsearch gespeichert, die folgende Informationen enthält:</p>Title;Descrition;Author;Year;Publisher;Ratings
<p>Wir haben diese Liste aus dem öffentlich verfügbaren <a href="https://www.kaggle.com/datasets/mohamedbakhet/amazon-books-reviews">Datensatz der Amazon-Buchrezensionen</a> extrahiert.</p><p>Wir haben einen <code>books</code> -Index mit den folgenden Elasticsearch-Mappings erstellt:</p>'mappings' : {
    'properties': {
        'title': {
            'type': 'text'
        },
        'description': {
            'type': 'text'
        },
        'author': {
            'type': 'text'
        },
        'year': {
            'type': 'short'
        },
        'publisher': {
            'type': 'keyword'
        },
        'rating': {
            'type': 'half_float'
        }
    }
}
<p>Der Wert <code>rating</code> ist der Durchschnitt der Ranking-Rezensionen aus der 2,9 GB großen Datei <a href="https://www.kaggle.com/datasets/mohamedbakhet/amazon-books-reviews?select=Books_rating.csv">Books_rating.csv</a> .</p><p><a href="https://github.com/elastic/elasticsearch-php-examples/blob/main/examples/ESQL/bulk.php">Hier</a> finden Sie das PHP-Skript, mit dem wir alle Bücher in Elasticsearch per Massenimport importiert haben. Die Massenverarbeitung dauerte 7 Sekunden und benötigte 28 MB RAM unter Verwendung von PHP 8.2.17. Mit dem vorgeschlagenen Mapping beträgt die Indexgröße in Elasticsearch etwa 62 MB.</p><h2>ES|QL-Ergebnisse einem PHP-Objekt oder einer benutzerdefinierten Klasse zuordnen</h2><p>Wir können ES|QL-Abfragen in PHP über den <code>esql()-&gt;query()</code> -Endpunkt ausführen. Das Ergebnis dieser Abfrage ist eine Tabellendatenstruktur. Dies wird in JSON mithilfe der Felder <code>columns</code> und <code>values</code> ausgedrückt. Im Feld <code>columns</code> haben wir die Definitionen <code>name</code> und <code>type</code> .</p><p>Hier ist ein Beispiel für eine ES|QL-Abfrage, um die Top-10-Bücher von Stephen King, sortiert nach den Nutzerbewertungen, abzurufen:</p>$query = &lt;&lt;&lt;EOD
    FROM books
    | WHERE author == "Stephen King"
    | SORT rating DESC
    | LIMIT 10
EOD;

$result = $client-&gt;esql()-&gt;query([
    'body' =&gt; ['query' =&gt; $query]
]);
<p>Das JSON-Ergebnis von Elasticsearch sieht wie folgt aus:</p>{
    "columns": [
        { "name": "author", "type": "text" },
        { "name": "description", "type": "text" },
        { "name": "publisher", "type": "keyword" },
        { "name": "rating", "type": "double" },
        { "name": "title", "type": "text" },
        { "name": "year", "type": "integer" }
    ],
    "values": [
        [
            "Stephen King",
            "The author ...",
            "Turtleback",
            5.0,
            "How writers write",
            2002
        ],
        [
            "Stephen King",
            "In Blockade Billy, a retired coach...",
            "Simon and Schuster",
            5.0,
            "Blockade",
            2010
        ],
        [
            "Stephen King",
            "A chilling collection of twenty horror stories.",
            "Signet Book",
            4.55859375,
            "Night Shift (Signet)",
            1979
        ],
        ...
    ]
}
<p>In diesem Beispiel haben wir 6 Eigenschaften (Autor, Beschreibung, Verlag, Bewertung, Titel, Jahr) zu einem Buch und 10 Ergebnisse, alle Bücher von Stephen King.</p><p>Eine Liste aller in ES|QL unterstützten Datentypen finden Sie <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/esql-limitations.html#esql-supported-types">hier</a>.</p><p>Das <code>$result</code> -Antwortobjekt kann als Array, als Zeichenkette oder als Objekt aufgerufen werden (siehe <a href="https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/connecting.html#client-usage">hier</a> für weitere Informationen).</p><p>Mithilfe der Objektschnittstelle können wir über Eigenschaften und Indizes auf die Werte zugreifen. Beispielsweise gibt <code>$result-&gt;values[0][4]</code> den Titel (4) des ersten Buches (0) in der Liste zurück, <code>$result-&gt;values[1][3]</code> die Bewertung (3) des zweiten Buches (1) usw. Denken Sie daran, dass der Index eines Arrays in PHP bei Null beginnt.</p><p>Diese Schnittstelle mag für einige Anwendungsfälle ausreichend sein, aber in den meisten Fällen möchten wir als Ergebnis ein Array von Objekten erhalten.</p><p>Um das Ergebnis in ein Array von Objekten abzubilden, können wir die neue <a href="https://github.com/elastic/elasticsearch-php/issues/1398">mapTo()-</a> Funktion von elasticsearch-php verwenden.</p><p>Diese Funktion ist direkt im <a href="https://github.com/elastic/elasticsearch-php/blob/main/src/Response/Elasticsearch.php">Elasticsearch-Antwortobjekt</a> verfügbar. Das bedeutet, Sie können wie folgt darauf zugreifen:</p>$books = $result-&gt;mapTo(); // Array of stdClass
foreach ($books as $book) {
    printf(
        "%s, %s, %d, Rating: %.2f\n",
        $book-&gt;author,
        $book-&gt;title,
        $book-&gt;year,
        $book-&gt;rating
    );
}
<p>Wenn Sie eine benutzerdefinierte Buchklasse haben, können Sie das Ergebnis mithilfe dieser Klasse wie folgt abbilden:</p>class Book
{
    public string $author;
    public string $title;
    public string $description;
    public int $year;
    public float $rating;
}

$books = $result-&gt;mapTo(Book::class); // Array of Book
<p>Wenn Ihre Klasse neben den im ES|QL-Ergebnis enthaltenen Eigenschaften noch weitere Eigenschaften besitzt, funktioniert dies ebenfalls. Die Funktion <code>mapTo()</code> verwendet nur die Eigenschaften, die als Spalten des ES|QL-Ergebnisses zurückgegeben werden.</p><p>Sie können alle in diesem Artikel genannten Beispiele <a href="https://github.com/elastic/elasticsearch-php-examples/tree/main/examples/ESQL">hier</a> herunterladen.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/esql-php-map-object-class</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/esql-php-map-object-class</guid>
    <category><![CDATA[ES|QL]]></category>
    <category><![CDATA[PHP]]></category>
    <dc:creator><![CDATA[Enrico Zimuel]]></dc:creator>
    <pubDate>Mon, 08 Apr 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>