<?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[Index-Daten - 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[Index-Daten - 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/index-data</link>
    </image>
    <link>https://www.elastic.co/de/search-labs/blog/category/index-data</link>
    <atom:link href="https://www.elastic.co/de/search-labs/rss/category/index-data.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[de]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 22:10:45 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Wenn TSDS auf ILM trifft: Gestaltung von Zeitreihendatenströmen, die verspätete Daten nicht ablehnen]]></title>
    <description><![CDATA[Interaktion zwischen den Zeitgrenzen von TSDS und den ILM-Phasen und Erstellung von Richtlinien, die verspätet eintreffende Metriken tolerieren.]]></description>
    <content:encoded><![CDATA[<p>Kürzlich habe ich den Metrik-Cluster eines Kunden von „alles in der Hot-Tier-Ebene“ auf eine Heiß-Kalt-Eingefroren-Architektur migriert. Es war eine Veränderung, die ich schon dutzende Male zuvor vorgenommen hatte. Innerhalb weniger Minuten stellte Logstash die Datenübertragung vollständig ein.</p><p>Elasticsearch lehnte verspätet eintreffende Metriken ab. Dies führte zu Verzögerungen in der Pipeline. Dadurch wurden wiederum weitere verspätete Daten generiert, was noch mehr Ablehnungen zur Folge hatte. Schließlich kam die Pipeline vollständig zum Stillstand.</p><p>Wir mussten die Daten aus einem Snapshot wiederherstellen, die Daten neu indizieren und die Ingestion-Pipeline neu gestalten, um die Wiederherstellung zu ermöglichen.</p><p>Die eigentliche Ursache lag nicht in der Verwaltung des Indexlebenszyklus (ILM) selbst. Es ging um Zeitreihendatenströme (TSDS) und wie diese zeitgebundene Sicherungsindizes erzwingen.</p><p>TSDS kann die Speicherplatzanforderungen für Metriken um 40–70 % reduzieren, aber die architektonischen Änderungen, die TSDS effizient machen, verändern auch das Verhalten von Indizes im Laufe der Zeit. Diese Änderungen sind wichtig bei der Gestaltung von ILM-Richtlinien oder wenn Ihre Ingestion-Pipelines möglicherweise verspätet eintreffende Daten erzeugen.</p><h2>TL;DR</h2><p>Bei Verwendung von TSDS:</p><ul><li><p>Sicherungsindizes akzeptieren nur Dokumente innerhalb eines bestimmten Zeitfensters.</p></li><li><p>Wenn verspätete Daten eintreffen, nachdem ein Index in den Status „kalt“ oder „eingefroren“ versetzt wurde, weist Elasticsearch diese Dokumente zurück oder leitet sie, falls konfiguriert, an den Fehlerspeicher weiter.</p></li></ul><p>Designregel:</p>warm_min_age &gt; rollover_max_age + maximum_expected_lateness<h2>Was ist ein Zeitreihendatenstrom?</h2><p>Ein<em> Zeitreihendatenstrom</em> (TSDS) ist ein spezieller Datenstrom, der für Metrikdaten optimiert ist. Die Daten werden so weitergeleitet, dass zugehörige Dokumente innerhalb derselben Shards liegen, wodurch sie für Abfrage und Abruf optimiert werden. So funktioniert dies in Elasticsearch:</p><p>Jedes Dokument enthält:</p><ul><li><p>Ein Zeitstempel.</p></li><li><p>Dimensionsfelder, die die Zeitreihen identifizieren.</p></li><li><p>Metrische Felder, die Messwerte darstellen.</p></li></ul><p>Dazu ein paar Beispiele:</p><ul><li><p>CPU-Auslastung pro Host.</p></li><li><p>Anfragenlatenzen pro Dienst.</p></li><li><p>Temperaturmessungen pro Sensor.</p></li></ul><p><em>Dimensionen </em>geben an, was wir messen möchten, während <em>Metriken </em>Werte darstellen, die sich im Laufe der Zeit ändern.</p><h3>Abmessungen</h3><p>Die Abmessungen beschreiben das gemessene Objekt.</p><p>Beispiele:</p>host.name
service.name
container.id<p>Wir definieren sie in den Mappings mit:</p>time_series_dimension: true<h3>Metriken</h3><p>Metriken stellen numerische Werte dar und werden wie folgt definiert:</p>time_series_metric<p>Gängige Arten von Metriken:</p><ul><li><p>Messanzeigen: Werte, die steigen und fallen.</p></li><li><p>Zähler: Werte, die bis zum Zurücksetzen ansteigen.</p></li></ul><p>Elastic Agent sammelt in erster Linie Metriken und Protokolldaten. Selbst wenn Sie also keine TSDS-Indizes manuell aktiviert haben, können diese dennoch in Ihrem Cluster vorhanden sein.</p><h3>Das _tsid-Feld</h3><p>Elasticsearch generiert intern einen <code>_tsid</code>-Wert aus Dimensionsfeldern. Dadurch können Dokumente mit identischen Abmessungen an denselben Shard weitergeleitet werden, was folgende Vorteile mit sich bringt:</p><ul><li><p>Kompression.</p></li><li><p>Abfrageort.</p></li><li><p>Aggregationsleistung.</p></li></ul><h2>Der wesentliche Unterschied: zeitgebundene Sicherungsindizes</h2><p>Herkömmliche Datenströme schreiben immer in den aktuellsten Sicherungsindex, der als <em>Schreibindex</em> bezeichnet wird, aber TSDS verhält sich anders.</p><p>Jeder TSDS-Sicherungsindex hat ein definiertes Zeitfenster und akzeptiert nur Dokumente mit <code>@timestamp</code>-Werten, die in dieses Zeitfenster fallen:</p>GET _data_stream/my-metrics-data-stream


     "index_mode": "time_series",
     "time_series": {
       "temporal_ranges": [
         {
           "start": "2026-01-15T14:35:50.000Z",
           "end": "2026-03-16T11:34:40.000Z"
         }
       ]
     }<p>Wenn ein Dokument indexiert wird, leitet Elasticsearch es an den für diesen Zeitstempel zuständigen Sicherungsindex weiter. Das bedeutet, dass ein TSDS im Gegensatz zu herkömmlichen Indizes gleichzeitig auf mehrere Sicherungsindizes schreiben kann.</p><p>Zum Beispiel:</p><ul><li><p>Echtzeit-Daten → aktuellster Index.</p></li><li><p>Verspätete Daten → ein früherer Index, der diesen Zeitbereich abdeckt.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7b001853af30d5f8/6a17dc2cfaa9137a7d93c751/31af2bb3b3dc24db8342e791e1db77a44659ba7a-1589x502.png" alt="Zeitleiste, die zeigt, wie ein verspätetes Dokument einem älteren Index und ein aktuelles Dokument dem neuesten Index zugeordnet wird." /><h2>Gestaltung für verspätet eintreffende Daten</h2><p>Echte Ingestion-Pipelines liefern Metriken nur selten perfekt und pünktlich. Die Metriken können sich aufgrund von Netzwerkausfällen, Rückständen auf dem Übertragungsweg, Batch-Ingestion und dem Ausfall von Edge-Geräten verzögern, die sich dann wieder verbinden und den Rückstand aufholen.</p><p>Herkömmliche Indizes gleichen diese Verzögerungen stillschweigend aus. TSDS tut dies nicht.</p><p>Wenn der Zeitstempel eines Dokuments außerhalb des Bereichs der beschreibbaren Sicherungsindizes liegt, wird es von Elasticsearch abgelehnt. Das bedeutet, dass Ihre ILM-Richtlinie verspätete Daten berücksichtigen muss.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6e8eae1b2ddad142/6a17dc2e1d1b8335a793e35c/32a103b95b20e31615c214271e27811a7ee315ae-1999x691.png" alt="Zeitplan für den Index-Lebenszyklus" /><h2>Die kritische Einschränkung</h2><p>Unterstützende Indizes müssen lange genug beschreibbar bleiben, um verzögerte Daten zu akzeptieren.</p><p>Konkret bedeutet dies:</p>time_until_readonly &gt; maximum_expected_lateness<p>Da ILM das Alter ab dem Rollover misst, lautet die operative Regel:</p>warm_or_cold_min_age &gt; rollover_max_age + maximum_expected_lateness<p></p><p>Wenn beispielsweise Metriken bis zu sechs Stunden verspätet eintreffen können, müssen Indizes mindestens sechs Stunden nach dem Rollover beschreibbar bleiben.</p><p></p><p>Dass diese Einschränkung nicht berücksichtigt wurde, war genau die Ursache für den zuvor beschriebenen Ingestion-Fehler. Verspätet eintreffende Daten wurden an einen früheren Index weitergeleitet, der sich bereits im Cold Tier befand und daher für Schreibvorgänge gesperrt war.</p><p></p><h2>Umgang mit abgelehnten Dokumenten</h2><p>Wenn TSDS ein Dokument ablehnt, gibt Elasticsearch eine Fehlermeldung aus, die darauf hinweist, dass der Zeitstempel nicht in den Bereich der beschreibbaren Indizes fällt. Die Art und Weise, wie Ihre Ingestion-Pipeline mit diesem Fehler umgeht, bestimmt, ob Sie Daten verlieren oder die Ingestion unterbrechen.</p><p>Der primäre Mechanismus für den Umgang mit abgelehnten Dokumenten ist der Fehlerspeicher.</p><h3>Fehlerspeicher (empfohlen in Elasticsearch 9.1+)</h3><p>Mit Elasticsearch 9.1 wurde der Fehlerspeicher eingeführt, der automatisch abgelehnte Dokumente erfasst. Anstatt Fehler an Clients zurückzuleiten, schreibt Elasticsearch fehlgeschlagene Dokumente in einen dedizierten Fehlerindex innerhalb des Datenstroms.</p><p>Sie können Fehler inspizieren, indem Sie:</p>GET metrics-myapp::failures/_search<p>Die Verwendung des Fehlerspeichers verhindert, dass Ingestion-Pipelines aufgrund von Ablehnungsfehlern überlastet werden, während fehlgeschlagene Daten für Analysen oder <a href="https://www.elastic.co/docs/manage-data/data-store/data-streams/reindex-tsds">erneute Indexierung</a> aufbewahrt werden.</p><h2>Probleme bei der Ablehnung überwachen</h2><p>Bei spät auftretenden Problemen zeigen sich zunächst meist Ingestion-Anomalien. Zunächst fallen sie Ihnen möglicherweise auf als:</p><ul><li><p>Plötzliche Rückgänge der Indexierungsrate.</p></li><li><p>Sprunghafte Anstiege bei abgelehnten Dokumenten.</p></li><li><p>Eine wachsende Anzahl von Einträgen im Fehlerspeicher.</p></li><li><p>Abweichungen zwischen den Eingangs- und Ausgangswerten der Pipeline.</p></li></ul><p>Durch die Warnmeldung bei diesen Signalen können die Betreiber Probleme erkennen, bevor es zu einem Stillstand der Pipelines kommt. Workflows, Machine Learning-Jobs und andere Mechanismen können verwendet werden, um die Erkennung und Benachrichtigung zu automatisieren.</p><h2>Migrationscheckliste für TSDS + ILM</h2><p>Wenn Sie einen Metrik-Cluster auf TSDS migrieren, ILM-Tiering einsetzen oder auf eine Elasticsearch-Version upgraden, bei der die Metriken standardmäßig als TSDS erfasst sind, überprüfen Sie diese Punkte zuerst.</p><h3><strong>1. Ingestion-Latenz messen</strong></h3><p>Vor der Änderung der ILM-Richtlinien ist Folgendes festzulegen:</p><ul><li><p>Normale Ingestion-Verzögerung.</p></li><li><p>Maximale Verzögerung bei Vorfällen.</p></li><li><p>Verzögerungen durch Batch-Pipelines.</p></li></ul><p>Ihr ILM-Design muss die maximale realistische Verzögerung berücksichtigen.</p><h3><strong>2. Indexzeitfenster überprüfen</strong></h3><p>Inspizieren Sie Ihre TSDS-Sicherungsindizes:</p>GET _data_stream/&lt;your-stream&gt;<p>Suchen Sie nach:</p><ul><li><p><code>time_series.start_time</code></p></li><li><p><code>time_series.end_time</code></p></li></ul><p>Diese Grenzen legen fest, welche Indizes Dokumente aufnehmen können. Das Verständnis dieser Zeitfenster kann Ihnen dabei helfen, zu ermitteln, wie spät Daten eintreffen dürfen, bevor sie abgelehnt werden.</p><h3><strong>3. Die Dimension der „heißen“ Ebene für verspätet eintreffende Daten bestimmen</strong></h3><p>Stellen Sie sicher, dass die unterstützenden Indizes lange genug beschreibbar bleiben, um verzögerte Daten zu verarbeiten.</p><p>Betriebsregel:</p><ul><li><p><code>warm_min_age &gt; rollover_max_age + maximum_expected_lateness</code></p></li></ul><p>Denken Sie daran, dass Indizes mindestens sechs Stunden beschreibbar bleiben müssen, wenn Metriken sechs Stunden zu spät eintreffen.</p><h3><strong>4. Entscheiden Sie, wie mit abgelehnten Dokumenten umgegangen werden soll</strong></h3><p>Wählen Sie eine Strategie, bevor Sie TSDS aktivieren:</p><ul><li><p>Fehlerspeicher (empfohlen in Elasticsearch 9.1+).</p></li><li><p>Warteschlange für unzustellbare Nachrichten in Logstash.</p></li><li><p>Fallback-Index für verspätete Eingänge.</p></li><li><p>Akzeptanz von begrenztem Datenverlust.</p></li></ul><h3><strong>5. Ingestion-Status überwachen</strong></h3><p>Warnmeldungen hinzufügen für:</p><ul><li><p>Die Indexierungsrate sinkt.</p></li><li><p>Abgelehnte Dokumente.</p></li><li><p>Das Fehlerspeicherwachstum.</p></li><li><p>Diskrepanzen zwischen Pipeline-Eingabe und -Ausgabe.</p></li></ul><p>Verspätete Datenprobleme treten oft zuerst als Ingestion-Anomalien auf.</p><h2>Zusammenfassung</h2><p>Zeitreihendatenströme bieten erhebliche Speicher- und Leistungsverbesserungen für Metrik-Workloads, bringen aber eine wichtige architektonische Änderung mit sich: Sicherungsindizes sind zeitgebunden, was das Verhalten von ILM beeinflusst.</p><p>Bei Verwendung von TSDS:</p><ul><li><p>Indizes müssen lange genug beschreibbar bleiben, um verzögerte Daten zu akzeptieren.</p></li><li><p>Ingestion-Pipelines sollten abgelehnte Dokumente sicher verarbeiten.</p></li></ul><p>Die wichtigste Regel lautet:</p>warm_min_age &gt; rollover_max_age + maximum_expected_lateness<p>Wenn Sie Ihre ILM-Richtlinien unter Berücksichtigung dieser Einschränkung gestalten, eignet sich TSDS hervorragend für Metrik-Workloads.</p><p>Wenn Sie dies jedoch ignorieren, könnte Ihre Ingestion-Pipeline diese Zeitgrenzen auf die harte Tour erfahren.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/tsds-ilm-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/tsds-ilm-elasticsearch</guid>
    <category><![CDATA[Index-Daten]]></category>
    <category><![CDATA[Vektordatenbank]]></category>
    <dc:creator><![CDATA[Bret Wortman]]></dc:creator>
    <pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elastic Open Web Crawler als Code]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie GitHub Actions verwenden, um Elastic Open Crawler-Konfigurationen zu verwalten, sodass Änderungen, die wir in das Repository übertragen, automatisch auf die bereitgestellte Instanz des Crawlers angewendet werden.]]></description>
    <content:encoded><![CDATA[<p>Mit <a href="https://github.com/elastic/crawler">Elastic Open Web Crawler</a> und seiner CLI-gesteuerten Architektur lassen sich versionierte Crawler-Konfigurationen und eine CI/CD-Pipeline mit lokalen Tests jetzt recht einfach realisieren.</p><p>Traditionell war die Verwaltung von Webcrawlern ein manueller, fehleranfälliger Prozess. Dabei ging es um das direkte Bearbeiten von Konfigurationen in der Benutzeroberfläche sowie um das Klonen von Crawl-Konfigurationen, das Zurücksetzen von Einstellungen, die Versionsverwaltung und vieles mehr. Die Behandlung von Crawler-Konfigurationen als Code löst dieses Problem, indem sie die gleichen Vorteile bietet, die wir von der Softwareentwicklung erwarten: Wiederholbarkeit, Nachvollziehbarkeit und Automatisierung.</p><p>Dieser Workflow erleichtert es, den Open Web Crawler in Ihre CI/CD-Pipeline für Rollbacks, Backups und Migrationen einzubinden – Aufgaben, die mit früheren Elastic Crawlern wie dem Elastic Web Crawler oder dem App Search Crawler wesentlich schwieriger waren.</p><p>In diesem Artikel erfahren Sie, wie Sie:</p><ul><li><p>Verwalten Sie unsere Crawl-Konfigurationen mit GitHub.</p></li><li><p>Eine lokale Testumgebung für Pipelines vor der Bereitstellung einrichten</p></li><li><p>Wir erstellen eine Produktionsumgebung, um den Webcrawler jedes Mal mit neuen Einstellungen auszuführen, wenn wir Änderungen an unseren Hauptzweig übertragen.</p></li></ul><p>Das Projekt-Repository finden Sie <a href="https://github.com/llermaly/elastic-open-crawler-as-code"><em><strong>hier</strong></em></a><em><strong>. </strong></em><em>Zum Zeitpunkt der Erstellung dieses Dokuments verwende ich Elasticsearch 9.1.3 und Open Web Crawler 0.4.2.</em></p><h2>Voraussetzungen</h2><ul><li><p>Docker Desktop</p></li><li><p>Elasticsearch-Instanz</p></li><li><p>Virtuelle Maschine mit SSH-Zugriff (z. B. AWS EC2) und installiertem Docker</p></li></ul><h2>Schritte</h2><ol><li><p>Ordnerstruktur</p></li><li><p>Raupenkonfiguration</p></li><li><p>Docker-Compose-Datei (lokale Umgebung)</p></li><li><p>GitHub Actions</p></li><li><p>Lokale Tests</p></li><li><p>Bereitstellung in der Produktionsumgebung</p></li><li><p>Änderungen vornehmen und erneut bereitstellen</p></li></ol><h2>Ordnerstruktur</h2><p>Für dieses Projekt werden wir folgende Dateistruktur verwenden:</p>├── docker-compose.yml # Local elasticsearch + crawler
├── config/crawler-config.yml # Crawler config
├── .github/workflows/deploy.yml # GH Action to deploy changes
├── local.sh # Script to run our local crawler<h2>Raupenkonfiguration</h2><p>Unter <code>crawler-config.yml,</code> wird Folgendes eingetragen:</p>output_sink: elasticsearch
output_index: web-crawl-index
max_crawl_depth: 1

elasticsearch:
  host: ${ES_HOST}
  api_key: ${ES_API_KEY}
     
domains:
  - url: https://web-scraping.dev
    seed_urls:
      - https://web-scraping.dev/product/1
      - https://web-scraping.dev/product/2
      - https://web-scraping.dev/product/3<p>Dies führt einen Crawl von <a href="https://web-scraping.dev/products">https://web-scraping.dev/products</a> durch, einer simulierten Website für Produkte. Wir werden nur die ersten drei Produktseiten durchsuchen. Die Einstellung <code>max_crawl_depth</code> verhindert, dass der Crawler mehr Seiten als die als <code>seed_urls</code> definierten Seiten entdeckt, indem er die darin enthaltenen Links nicht öffnet.</p><p>Elasticsearch <code>host</code> und <code>api_key</code> werden dynamisch befüllt, abhängig von der Umgebung, in der das Skript ausgeführt wird.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7d37b966aafbd3c1/6a17ef9842022946e929f6b9/f9831034e1c4ccb554d37bdd188f2824338355a0-890x624.png" alt="Die Produktseite für „Schokoladenbox“ von der Domain web-scraping.dev, einer Testseite für Web-Scraping. Auf der Seite werden der Produkttitel, das Bild, die Beschreibung sowie die HTML-Elemente für Preis- und Kaufbuttons angezeigt." /><h2>Docker-Compose-Datei (lokale Umgebung)</h2><p>Für die lokale Umgebung <code>docker-compose.yml,</code> werden wir den Crawler und einen einzelnen Elasticsearch-Cluster + Kibana bereitstellen, damit wir unsere Crawling-Ergebnisse <em><strong>vor</strong></em> der Bereitstellung in der Produktionsumgebung einfach visualisieren können.</p>services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.1.3
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    ports:
      - "9200:9200"
    networks: [esnet]
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9200"]
      interval: 5s
      timeout: 5s
      retries: 10

  kibana:
    image: docker.elastic.co/kibana/kibana:9.1.3
    environment:
      - ELASTICSEARCH_HOSTS=http://es01:9200
    ports:
      - "5601:5601"
    networks: [esnet]
    depends_on: [es01]

  crawler:
    image: docker.elastic.co/integrations/crawler:0.4.2
    environment:
      - ES_HOST=http://es01:9200
      - CRAWLER_JRUBY_OPTS=--server
    container_name: crawler
    volumes:
      - ./config:/home/app/config
    networks: [esnet]
    entrypoint: ["/home/app/bin/crawler", "crawl", "/home/app/config/crawl-config-final.yml"]
    stdin_open: true
    tty: true

networks:
  esnet:
    driver: bridge<p>Beachten Sie, wie der Crawler wartet, bis Elasticsearch bereit ist, ausgeführt zu werden.</p><h2>GitHub Actions</h2><p>Nun müssen wir eine GitHub-Aktion erstellen, die die neuen Einstellungen kopiert und den Crawler bei jedem Push auf den Hauptzweig in unserer virtuellen Maschine ausführt. Dadurch wird sichergestellt, dass wir immer die aktuellste Konfiguration im Einsatz haben, ohne manuell in die virtuelle Maschine eingreifen zu müssen, um Dateien zu aktualisieren und den Crawler auszuführen. Wir werden AWS EC2 als Anbieter virtueller Maschinen verwenden.</p><p>Der erste Schritt besteht darin, den Host (<code>VM_HOST</code>), den Maschinenbenutzer (<code>VM_USER</code>), den SSH-RSA-Schlüssel (<code>VM_KEY</code>), den Elasticsearch-Host (<code>ES_HOST</code>) und den Elasticsearch-API-Schlüssel (<code>ES_API_KEY</code>) zu den GitHub Action Secrets hinzuzufügen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb5a0fcfff9b7f997/6a17ef9a6df731d7d40a0fdf/e1075bc54151b4b94eac2a6bd2682e9997e6c709-1106x707.png" alt="Eine Konfigurationsseite für „Aktionen, Geheimnisse und Variablen“, auf der Repository-Geheimnisse wie VM_HOST, VM_KEY und VM_USER über eine webbasierte Oberfläche angezeigt werden." /><p>Auf diese Weise kann die Aktion auf unseren Server zugreifen, um die neuen Dateien zu kopieren und den Crawl auszuführen.</p><p>Nun erstellen wir unsere <code>.github/workflows/deploy.yml</code> -Datei:</p>name: Deploy

on:
  push:
    branches: [main]

jobs:
  Deploy:
    name: Deploy to EC2
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5

      - name: Deploy crawler
        env:
          HOSTNAME: ${{ secrets.VM_HOST }}
          USER_NAME: ${{ secrets.VM_USER }}
          PRIVATE_KEY: ${{ secrets.VM_KEY }}
          ES_HOST: ${{ secrets.ES_HOST }}
          ES_API_KEY: ${{ secrets.ES_API_KEY }}
        run: |
          # Save private key
          echo "$PRIVATE_KEY" &gt; private_key
          chmod 600 private_key

          # Generate final config locally
          envsubst &lt; config/crawler-config.yml &gt; config/crawl-config-final.yml

          # Copy the config folder to VM
          scp -o StrictHostKeyChecking=no -i private_key -r config ${USER_NAME}@${HOSTNAME}:~/config

          # SSH into VM and run crawler
          ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} &lt;&lt; EOF
            docker run --rm \
              -v ~/config:/config \
              docker.elastic.co/integrations/crawler:latest jruby \
              bin/crawler crawl /config/crawl-config-final.yml
          EOF<p>Diese Aktion führt jedes Mal die folgenden Schritte aus, wenn wir Änderungen an der Crawler-Konfigurationsdatei vornehmen:</p><ol><li><p>Tragen Sie den Elasticsearch-Host und den API-Schlüssel in die YAML-Konfiguration ein.</p></li><li><p>Kopieren Sie den Konfigurationsordner auf unsere VM</p></li><li><p>Stellen Sie über SSH eine Verbindung zu unserer VM her.</p></li><li><p>Führen Sie den Crawl mit der Konfiguration aus, die wir gerade aus dem Repository kopiert haben.</p></li></ol><h2>Lokale Tests</h2><p>Um unseren Crawler lokal zu testen, haben wir ein Bash-Skript erstellt, das den Elasticsearch-Host mit dem lokalen Docker-Repository befüllt und einen Crawl startet. Sie können <code>./local.sh</code> eingeben, um es auszuführen.</p>#!/bin/bash

# Exit on any error
set -e

# Load environment variables
export ES_HOST="http://es01:9200"

# Generate final crawler config
envsubst &lt; ./config/crawler-config.yml &gt; ./config/crawl-config-final.yml

# Bring everything up
docker compose up --build<p>Schauen wir uns die Kibana DevTools an, um zu bestätigen, dass<code> web-crawler-index</code> korrekt befüllt wurde:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt989660368fe14db8/6a17ef9b9da390c79ce46562/18551635e8265866e389a9632c4e4540958e4468-990x723.png" alt="Kibana DevTools-Code zur Bestätigung, dass der Webcrawler-Index korrekt eingerichtet ist." /><h2>Bereitstellung in der Produktionsumgebung</h2><p>Jetzt sind wir bereit, die Änderungen auf den Hauptzweig zu übertragen. Dadurch wird der Crawler in Ihrer virtuellen Maschine bereitgestellt und beginnt, Protokolle an Ihre Serverless Elasticsearch-Instanz zu senden.</p>git add .
git commit -m "First commit"
git push<p>Dadurch wird die GitHub-Aktion ausgelöst, die das Bereitstellungsskript innerhalb der virtuellen Maschine ausführt und mit dem Crawling beginnt.</p><p>Sie können die Ausführung der Aktion überprüfen, indem Sie zum GitHub-Repository gehen und den Tab „Aktionen“ aufrufen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt986f1a4e4f3288d2/6a17ef9c7f6f1584fdc09c10/67ba3a7164d7a8049fe5661264820826cb18ed64-667x325.png" alt="Die Aktionen werden im EC2-Tab eines GitHub-Repositorys bereitgestellt." /><h2>Änderungen vornehmen und erneut bereitstellen</h2><p>Vielleicht ist Ihnen aufgefallen, dass die <code>price</code> jedes Produkts Teil des Body-Felds des Dokuments ist. Ideal wäre es, den Preis in einem separaten Feld zu speichern, damit wir Filter darauf anwenden können.</p><p>Fügen wir diese Änderung zur Datei <code>crawler.yml</code> hinzu, um <a href="https://github.com/elastic/crawler/blob/main/docs/features/EXTRACTION_RULES.md">Extraktionsregeln</a> zu verwenden, mit denen der Preis aus der CSS-Klasse <code>product-price</code> extrahiert werden kann:</p>output_sink: elasticsearch
output_index: web-crawl-index
max_crawl_depth: 1

elasticsearch:
  host: ${ES_HOST}
  api_key: ${ES_API_KEY}
     
  # Index ingest pipeline to process documents before indexing          
  pipeline_enabled: true
  pipeline: pricing-pipeline

domains:
  - url: https://web-scraping.dev
    seed_urls:
      - https://web-scraping.dev/product/1
      - https://web-scraping.dev/product/2
      - https://web-scraping.dev/product/3
    extraction_rulesets:
      - url_filters:
          - type: ends
            pattern: /product/*
        rules:
          - action: extract
            field_name: price
            selector: .product-price
            join_as: string
            source: html<p>Wir sehen auch, dass der Preis ein Dollarzeichen (<code>$</code>) enthält, das wir entfernen müssen, wenn wir Bereichsabfragen ausführen wollen. Dafür können wir eine Ingest-Pipeline verwenden. Beachten Sie, dass wir in unserer neuen Crawler-Konfigurationsdatei oben darauf verweisen:</p>PUT _ingest/pipeline/pricing-pipeline
{
  "processors": [
    {
      "script": {
        "source": """
                ctx['price'] = ctx['price'].replace("$","")
            """
      }
    }
  ]
}<p>Wir können diesen Befehl in unserem Elasticsearch-Produktionscluster ausführen. Da die Entwicklungsversion ephemer ist, können wir die Pipeline-Erstellung in die <code>docker-compose.yml</code> -Datei integrieren, indem wir den folgenden Dienst hinzufügen. Beachten Sie, dass wir dem Crawler-Dienst auch eine <code>depends_on</code> hinzugefügt haben, damit er erst startet, nachdem die Pipeline erfolgreich erstellt wurde.</p> crawler:
    image: docker.elastic.co/integrations/crawler:0.4.2
    environment:
      - ES_HOST=http://es01:9200
      - CRAWLER_JRUBY_OPTS=--server
    container_name: crawler
    volumes:
      - ./config:/home/app/config
    networks: [esnet]
    entrypoint: ["/home/app/bin/crawler", "crawl", "/home/app/config/crawl-config-final.yml"]
    depends_on:
      pipeline-init:
        condition: service_completed_successfully
    stdin_open: true
    tty: true  


  pipeline-init:
    image: curlimages/curl:latest
    depends_on:
      es01:
        condition: service_healthy
    networks: [esnet]
    entrypoint: &gt;
        sh -c "
        echo 'Creating ingest pipeline...';
        curl -s -X PUT http://es01:9200/_ingest/pipeline/pricing-pipeline \\
          -H 'Content-Type: application/json' \\
          -d '{\"processors\":[{\"script\":{\"source\":\"ctx.price = ctx.price.replace(\\\"$\\\", \\\"\\\")\"}}]}';
        echo 'Pipeline created!';
        "<p>Führen wir nun <code>`./local.sh`</code> aus, um die Änderung lokal zu sehen:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f390aedf67cb4fe/6a17ef9eaf47b62bd2cde05b/dc1801599344a9f69f072b07ff828c4ba3815d7b-738x473.png" alt="Führen Sie `./local.sh` aus, um die Preisänderung lokal zu sehen." /><p>Großartig! Jetzt lasst uns die Veränderung vorantreiben:</p>git add crawler-config.yml
git commit -m "added price CSS selector"
git push<p>Um sicherzustellen, dass alles funktioniert, können Sie Ihre Produktions-Kibana-Datei überprüfen. Dort sollten die Änderungen sichtbar sein und der Preis als neues Feld ohne Dollarzeichen angezeigt werden.</p><h2>Fazit</h2><p>Mit dem Elastic Open Web Crawler können Sie Ihren Crawler als Code verwalten. Das bedeutet, dass Sie die gesamte Pipeline – von der Entwicklung bis zur Bereitstellung – automatisieren und beispielsweise ephemere lokale Umgebungen und Tests anhand der gecrawlten Daten programmatisch hinzufügen können.</p><p>Sie sind eingeladen, das offizielle Repository zu klonen und mit der Indizierung Ihrer eigenen Daten mithilfe dieses Workflows zu beginnen. In <a href="https://www.elastic.co/search-labs/blog/semantic-search-open-crawler">diesem Artikel</a> erfahren Sie auch, wie Sie eine semantische Suche auf den vom Crawler erzeugten Indizes durchführen.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elastic-open-crawler-config-as-code</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elastic-open-crawler-config-as-code</guid>
    <category><![CDATA[Index-Daten]]></category>
    <category><![CDATA[Operativer Betrieb]]></category>
    <dc:creator><![CDATA[Gustavo Llermaly]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt00e7c95012dc38cc/6a17efa0fbc5f80dad491b93/0ac41f55c85ad3f647cb0e0d750ed80bacd397f3-1036x581.png" length="0" type="image/png"/>
    <pubDate>Mon, 22 Sep 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Wie man Felder eines Elasticsearch-Index anzeigt]]></title>
    <description><![CDATA[Lernen Sie, wie Sie Felder eines Elasticsearch-Index mithilfe der _mapping- und _search-APIs, Unterfeldern, synthetischen _source-Daten und Laufzeitfeldern anzeigen können.]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel werden wir erläutern, wie man Felder eines Elasticsearch-Index anzeigt. Dies kann hilfreich sein, um die Struktur Ihrer Daten zu verstehen, bestimmte Felder zu identifizieren und Probleme zu beheben. Wir werden folgende Themen behandeln:</p><ol><li><p>Verwendung der <code>_mapping</code> -API zum Abrufen von Feldinformationen</p></li><li><p>Verwendung der <code>_search</code> API zum Anzeigen von Feldwerten</p></li><li><p>Unterfelder anzeigen</p></li><li><p>Synthetisches Feld „_source“</p></li><li><p>Laufzeitfelder</p></li></ol><h2>1. Verwendung der _mapping-API zum Abrufen von Feldinformationen</h2><p>Die <code>_mapping</code> API ermöglicht es Ihnen, die Mapping-Definition für einen oder mehrere Indizes abzurufen. Dies umfasst Informationen über die Felder, ihre Datentypen und weitere Eigenschaften. Um die Zuordnung für einen bestimmten Index abzurufen, verwenden Sie die folgende Anfrage:</p>GET /&lt;index_name&gt;/_mapping<p>Wenn Sie beispielsweise einen Index mit dem Namen <code>my_index</code> haben, können Sie dessen Zuordnung mit der folgenden Anfrage abrufen:</p>GET /my_index/_mapping<p>Die Antwort enthält die Mapping-Definition für den Index, die Informationen über die Felder und deren Eigenschaften enthält.</p><p>Es ist auch möglich, die Zuordnung eines bestimmten Feldes abzurufen. Dies kann nützlich sein, wenn Ihre Kartierung recht umfangreich ist und Sie sich nur auf ein bestimmtes Feld konzentrieren möchten. Um die Zuordnung eines bestimmten Feldes abzurufen, verwenden Sie die folgende Anfrage:</p>GET /my_index/_mapping/field/my_field<p>Sie können die Zuordnungen mehrerer Felder auch abrufen, indem Sie deren Namen durch Kommas trennen, wie in der folgenden Anfrage:</p>GET /my_index/_mapping/field/my_field_1,my_field_2,my_field_3<h2>2. Verwenden der _search-API zum Anzeigen von Feldwerten</h2><p>Um die Werte von Feldern in einem Elasticsearch-Index anzuzeigen, können Sie die <code>_search</code> API verwenden. Die <code>_search</code> API bietet Ihnen mehrere Möglichkeiten, die zurückgegebenen Felder zu steuern; die beiden wichtigsten sind:</p><ol><li><p><strong><code>_source</code></strong>Das Feld <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-source-field"><code>_source</code></a> enthält den ursprünglichen JSON-Dokumentkörper genau so, wie er indexiert wurde, einschließlich aller Änderungen, die durch Ingestionspipelines oder Vorverarbeitungsschritte vorgenommen wurden. Um bestimmte Felder aus dem Quelldokument anzuzeigen, implementieren Sie eine Quellfilterung, wie wir im Folgenden sehen werden.</p></li><li><p><strong><code>fields</code></strong>Mit dem Parameter <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrieve-selected-fields"><code>fields</code></a> können Sie beim Durchführen einer Suche bestimmte Felder aus Ihren Dokumenten auf Basis der Indexzuordnung abrufen. Im Gegensatz zu <code>_source</code> kann <code>fields</code> auch Werte aus gespeicherten Feldern, Dokumentwerten oder Laufzeitfeldern zurückgeben, ohne auf <code>_source</code> zu verweisen. Für Standardfelder ohne Dokumentwerte oder gespeicherte Einstellungen wird jedoch auf <code>_source</code> zurückgegriffen. Dies kann viele Vorteile mit sich bringen, wie zum Beispiel eine höhere Leistungsfähigkeit und mehr, wie wir im Folgenden sehen werden.</p></li></ol><h3>Verwendung des Feldes _source</h3><p>Standardmäßig gibt die<code> _search</code> -API das Feld <code>_source</code> zurück, welches das ursprüngliche, indizierte JSON-Dokument enthält. Um bestimmte Felder anzuzeigen, können Sie Filter im Parameter <code>_source </code>der Suchanfrage hinzufügen; dies wird als Quellfilterung bezeichnet.</p><p>Hier ist ein Beispiel für eine Suchanfrage, die die Werte der Felder <code>title </code>und <code>author</code> für Dokumente im Index <code>my_index</code> zurückgibt:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "_source": ["title", "author"]
}<p>In diesem Beispiel gibt der Parameter <code>_source</code> die zurückzugebenden Felder an.</p><p>Falls Sie noch mehr Kontrolle benötigen, können Sie die Eigenschaften <code>includes</code> und <code>excludes </code>des Objekts <code>_source</code> verwenden. Beispielsweise gibt die folgende Abfrage das Feld der obersten Ebene <code>title</code> und alle Unterfelder von <code>author</code> außer <code>author.description</code> zurück.</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "_source": {
     “includes”: [“title”, “author.*],
     “excludes”: [“author.description”]
  }
}<p>In diesem Beispiel verwenden wir das Muster <code>author.* </code> , um jedes direkte Unterfeld des Objekts <code>author </code>abzurufen. Dann schließen wir <code>author.description </code>explizit aus, sodass nur die übrigen Autorenfelder zurückgegeben werden. Beachten Sie, dass dies keine Leistungsverbesserungen mit sich bringt, da das Quell-JSON weiterhin geladen und analysiert werden muss, aber es kann die Größe der über das Netzwerk gesendeten Antwort verringern.</p><h3>Verwendung des Parameters „fields“</h3><p>Mit dem Parameter <code>fields</code> können Sie die in der Suchergebnisseinduktion zurückgegebenen Felder filtern. Die Verwendung <code>fields</code> anstelle von <code>_source</code> bietet mehrere Vorteile, darunter:</p><ul><li><p><strong>Verbesserte Performance: </strong><code>fields </code>kann Werte direkt aus <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-store">gespeicherten Feldern</a> oder <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/doc-values">Dokumentwerten</a> zurückgeben, ohne die vollständige <code>_source</code> laden zu müssen, wodurch die Größe der Antwortnutzlast kleiner wird.</p></li><li><p><strong>Formatierte Ausgabe:</strong> Bei Standardfeldern kann <code> fields</code> auf <code>_source</code> zurückgreifen, um die Werte zu erfassen. Dabei wird jedoch die Indexzuordnung herangezogen, um die Ausgabe korrekt zu formatieren, z. B. formatierte Datumsangaben, sodass sie mit den für Aggregationen und Sortierungen verwendeten Formaten konsistent sind.</p></li><li><p><strong>Zugriff auf Laufzeitfelder:</strong> <code>fields</code> kann Laufzeitfelder zurückgeben, die im ursprünglichen <code>_source</code> nicht existieren.</p></li><li><p>Weitere Vorteile finden Sie <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrieve-selected-fields#search-fields-param">hier</a>.</p></li></ul><p>Um beispielsweise nur die Felder <code>title</code> und <code>author</code> im Index <code>my_index</code> zurückzugeben, können Sie die folgende Suchanfrage verwenden:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "fields": ["title", "author"],
  "_source": false
}<p>In der obigen Abfrage setzen wir das Feld <code>_source </code>auf false, damit wir das Quelldokument nicht zurückgeben. Dadurch kann die Nutzlastgröße der Antwort drastisch reduziert werden. Beachten Sie jedoch, dass dies nur funktioniert, weil die Felder <code>title</code> und <code>author</code> vom Feldtyp <code>keyword </code>sind, bei dem standardmäßig <code>doc_values</code> aktiviert ist. Wenn das Feld <code>doc_values</code> nicht aktiviert hat und <code>_source</code> auf false gesetzt ist, hat Elasticsearch keine Möglichkeit, diese abzurufen, und sie werden in der Antwort übersprungen.</p><p>Wichtig zu beachten ist, dass die <code>fields</code> -Antwort immer ein Array von Werten für jedes Feld zurückgibt, selbst wenn es nur einen einzigen Wert gibt. Dies liegt daran, dass Elasticsearch keinen dedizierten Array-Typ besitzt und jedes Feld mehrere Werte haben kann. Für weitere Informationen zu Arrays in Elasticsearch klicken Sie <a href="http://elastic.co/docs/reference/elasticsearch/mapping-reference/array">hier</a>.</p><h3>Weitere Möglichkeiten zum Abrufen von Feldern</h3><p>Obwohl das Abrufen von Feldern mit <code>_source</code> oder <code>fields</code> die empfohlenen Methoden sind, stehen für bestimmte Anwendungsfälle verschiedene Methoden zur Verfügung, wie zum Beispiel:</p><p><strong>Doc-Wertfelder:</strong> Wenn Sie <code>_source</code> komplett vermeiden möchten, können Sie mit dem Parameter <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrieve-selected-fields#docvalue-fields"><code>docvalue_fields</code></a>suchen. Doc-Werte speichern die gleichen Feldwerte wie <code>_source</code> , jedoch in einer auf der Festplatte gespeicherten Datenstruktur, die für Sortierung und Aggregation optimiert ist.</p><p>Da es sich um separate Werte handelt, die nicht mit <code>_source</code> gespeichert sind, können Sie bestimmte Felder anfordern, ohne das gesamte <code>_source</code> zu laden. Dies ist nützlich, wenn Sie große Dokumente abfragen, aber nur wenige kleine Felder benötigen, die Dokumentwerte unterstützen. Ein weiterer Anwendungsfall für <code>docvalue_fields </code>besteht darin, dass Sie eine benutzerdefinierte Formatierung für die Felder <code>date</code> und <code>numeric</code> verwenden möchten, wie wir im folgenden Beispiel sehen werden.</p><p>Beachten Sie, dass dies nur für Felder funktioniert, für die Sie <code>doc_values</code> aktivieren, oder für Feldtypen, bei denen dies standardmäßig aktiviert ist, wie z. B. <code>keyword</code>, <code>date</code>, numerische Typen und <code>boolean</code>, nicht für <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/text"><code>text</code></a> oder <a href="https://www.elastic.co/docs/reference/elasticsearch/plugins/mapper-annotated-text-usage"><code>annotated_text</code></a>.</p><p>In diesem Beispiel verwenden wir den Parameter <code>docvalue_fields</code> , um die Felder <code>title</code>, <code>author</code> und <code>published</code> abzurufen, ohne das vollständige Dokument <code>_source</code> zu laden:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "docvalue_fields": [
    "title",
    "author",
    {
      "field": "published",
      "format": "epoch_millis"
    }
  ],
  "_source": false
}<p>Wenn diese Abfrage ausgeführt wird, greift Elasticsearch direkt auf die Werte in seinem spaltenorientierten Speicher auf der Festplatte zu, anstatt für jedes Dokument auf <code>_source </code>zu verweisen. Das Feld <code>published</code> wird dank des in der Abfrage angegebenen Parameters <code>format</code> im Format <code>epoch_millis</code> anstatt im Standardformat zurückgegeben.</p><p><strong>Gespeicherte Felder:</strong> Wenn Sie in der Zuordnung explizit bestimmte Felder als <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-store">gespeichert</a> markiert haben, können Sie mit dem Parameter <code>stored_fields</code> nach diesen Feldern filtern. Dies ist nützlich, wenn Sie kurze Antworten nur mit diesen spezifischen Feldern wünschen oder Felder, die Sie absichtlich zum späteren Abruf gespeichert haben. Es wird separat von <code>_source</code> gespeichert, daher ist diese Methode auch nützlich, um das Laden von <code>_source</code> zu vermeiden.</p><p>Wichtig zu beachten ist, dass diese Option standardmäßig deaktiviert und generell nicht empfehlenswert ist. Verwenden Sie stattdessen Quellfilter, um bestimmte Teilmengen des ursprünglichen Quelldokuments zurückzugeben.</p><p>In der folgenden Beispielabfrage verwenden wir den Parameter <code>stored_fields</code> , um das Feld <code>summary</code> abzurufen, das die Indexzuordnungskonfiguration ”<code>store”: true</code> hat.</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "stored_fields": ["summary"]
}<p>Wenn diese Abfrage ausgeführt wird, prüft Elasticsearch, ob dieses Feld mit <code>”store”: true</code> markiert wurde. Falls dies nicht der Fall ist, wird das Feld vollständig übersprungen.</p><h2>3. Unterfelder anzeigen</h2><p>Wenn Ihr Index Unterfelder enthält, können Sie die Punktnotation verwenden, um den Feldpfad im Parameter <code>fields</code> anzugeben. Beachten Sie, dass Unterfelder sich vom <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/nested">verschachtelten Feldtyp</a> unterscheiden. Wenn Sie beispielsweise ein Unterfeld mit dem Namen <code>address.city</code> haben, können Sie es wie folgt in die Suchergebnisseinlösung einbinden:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "fields": ["title", "author", "address.city"],
  "_source": false
}<p>In diesem Beispiel enthält die Suchergebnisseinsendung die Werte der Felder <code>title</code>, <code>author</code> und <code>address.city</code> .</p><h2>4. Synthetische Quelle</h2><p>Wenn Sie die Funktionalität der Verwendung von<code> _source</code> beibehalten, aber gleichzeitig Speicherplatz sparen möchten, haben Sie die Möglichkeit, in Ihrer Indexzuordnung synthetisches <code>_source</code> zu verwenden. Die Funktion <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-source-field#synthetic-source">Synthetic </a><a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/mapping-source-field#synthetic-source"><code>_source</code></a> ermöglicht es Elasticsearch, die <code>_source</code> aus vorhandenen Daten wie gespeicherten Feldern und Dokumentwerten zu rekonstruieren, selbst wenn <code>_source</code> deaktiviert ist. Dadurch lässt sich viel Speicherplatz sparen, allerdings auf Kosten etwas geringerer Abfragegeschwindigkeiten, da die Rekonstruktion in Echtzeit erfolgt. Aktivieren Sie diese Funktion, indem Sie die folgenden Werte in Ihren Indexeinstellungen verwenden:</p>PUT idx
{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  }
}<p>Zu den Vorteilen der Verwendung von synthetischem <code>_source </code>gehören: vollständige Dokumentanzeige bei Verwendung der <code>_search</code> API, Quellfilterung und Kompatibilität mit anderen Funktionen und Tools wie Kibana, die die Verfügbarkeit <code>_source</code> voraussetzen, und das alles, ohne dass das vollständige <code>_source</code> Dokument gespeichert werden muss.</p><h2>5. Laufzeitfelder</h2><p><a href="https://www.elastic.co/docs/manage-data/data-store/mapping/runtime-fields">Mit Laufzeitfeldern</a> können Sie skriptgesteuerte Felder zur Abfragezeit oder in Ihrer Indexzuordnung unter einem Laufzeitblock definieren. Diese Felder werden nie indiziert, daher erhöht das Hinzufügen eines Laufzeitfelds nicht die Indexgröße, es wird aber niemals in <code>_source</code> angezeigt. Die in der Zuordnung definierten Laufzeitfelder sind persistent und für alle Abfragen verfügbar, während die zur Abfragezeit definierten Laufzeitfelder temporär sind und nur in dieser Suchanfrage verfügbar sind.</p><p>Der Hauptvorteil der Verwendung von Laufzeitfeldern besteht darin, dass man Felder zu Dokumenten hinzufügen kann, nachdem man sie bereits importiert hat, was die Zuordnungsentscheidungen vereinfacht. Laufzeitfelder eignen sich auch hervorragend, um Ihre Dokumente mit Werten anzureichern, die im Originaldokument nicht vorhanden sind, sondern mithilfe eines Skripts generiert werden, z. B. durch Formatieren einer Zeichenkette oder Berechnen einer Punktzahl.</p><p>Es ist außerdem zu beachten, dass Laufzeitfelder die Leistung beeinträchtigen können, da für jedes Dokument im Ergebnissatz ein Skript ausgeführt werden muss. Um <a href="https://www.elastic.co/docs/manage-data/data-store/mapping/retrieve-runtime-field">ein Laufzeitfeld abzurufen</a>, können Sie auch den Parameter <code>fields</code> der API <code>_search</code> verwenden.</p><h2>Fazit</h2><p>Die Anzeige von Feldern eines Elasticsearch-Index kann von der einfachen Abfrage von Werten mithilfe der Indexzuordnung oder <code>_source</code> bis hin zu fortgeschritteneren Methoden mit <code>fields</code>, <code>docvalue_fields</code> oder Laufzeitfeldern für mehr Kontrolle und Effizienz reichen. Das Verständnis der Vor- und Nachteile verschiedener Methoden ist der Schlüssel zur Optimierung Ihrer Sucherfahrung. Egal ob Sie Nutzdaten optimieren, Dokumente anreichern oder synthetische Daten <code>_source</code> verwenden, um Speicherplatz zu sparen, Elasticsearch bietet Ihnen zahlreiche Tools und Funktionen, um die benötigten Daten so zu finden, wie Sie sie benötigen. Mithilfe dieser Techniken können Sie die Struktur Ihrer Daten verstehen, bestimmte Felder identifizieren und Probleme beheben.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-index-show-fields</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-index-show-fields</guid>
    <category><![CDATA[Index-Daten]]></category>
    <category><![CDATA[Mappings]]></category>
    <dc:creator><![CDATA[JD Armada]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd041e871a8935448/6a17de320b0bedf404dd34ab/23b96aaa1a38b1f4747b4a87695d816f24c0cf70-720x421.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 06 Aug 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Ruby-Skripting in Logstash]]></title>
    <description><![CDATA[Erfahren Sie mehr über das Logstash Ruby Filter-Plugin für die erweiterte Datentransformation in Ihrer Logstash-Pipeline.]]></description>
    <content:encoded><![CDATA[<p>Logstash ist eine Datenverarbeitungspipeline, die Daten aus verschiedenen Quellen aufnimmt, transformiert und an die von Ihnen gewählten Ziele sendet. Filter-Plugins sind für diesen Prozess unerlässlich; sie führen spezifische Operationen an Ihren Daten durch, während diese die Datenpipeline durchlaufen.</p><p>Logstash enthält mehrere integrierte Filter für häufige Aufgaben wie das Parsen, Anreichern und Modifizieren von Daten. Manchmal stößt man jedoch auf Szenarien, die eine benutzerdefinierte Logik erfordern, die über das hinausgeht, was diese Standardfilter bieten können. Hier kommt das <a href="https://www.elastic.co/docs/reference/logstash/plugins/plugins-filters-ruby">Ruby-Filter-Plugin</a> ins Spiel.</p><p><strong>Mit dem Ruby-Filter-Plugin können Sie benutzerdefinierten Ruby-Code direkt in Ihrer Logstash-Pipeline ausführen.</strong> Wenn Standardfilter nicht ausreichen, ermöglicht Ihnen der Ruby-Filter die Durchführung komplexer Datentransformationen, die Implementierung benutzerdefinierter Geschäftslogik oder die Integration mit externen Systemen.</p><p>In diesem Blogbeitrag zeigen wir Ihnen, wie Sie Ruby-Filter verwenden – von den Grundlagen bis hin zu fortgeschrittenen Anwendungsfällen.</p><h2>Wann sollte man den Ruby-Filter verwenden?</h2><p>Als beratender Architekt bei Elastic sehe ich oft, dass Kunden Logstash für die Datenverarbeitungspipeline verwenden, obwohl es heutzutage keine hochmoderne Datenverarbeitungs-Engine mehr ist. Bei komplexen Datenmanipulationen oder benutzerdefinierter Logik stoßen sie häufig an die Grenzen von Standardfiltern. In diesen Fällen kann der Ruby-Filter dazu beitragen, diese Herausforderungen zu bewältigen.</p><p>Der Ruby-Filter ist nützlich, wenn die Standard-Logstash-Filter Ihre spezifischen Anforderungen nicht erfüllen können. Hier einige typische Anwendungsfälle:</p><ul><li><p><strong>Tief verschachtelte Datenmanipulation</strong>: Komplexe JSON-Strukturen, Arrays innerhalb von Arrays modifizieren oder Daten dynamisch anhand ihres Inhalts umstrukturieren.</p></li><li><p><strong>Erweiterte Stringverarbeitung</strong>: Strukturierte Daten aus unstrukturiertem Text analysieren und extrahieren</p></li><li><p><strong>Implementierung komplexer Geschäftslogik</strong>: Erstellen benutzerdefinierter Transformationen, die bedingte Logik, Schleifen oder komplexe Berechnungen erfordern.</p></li></ul><h2>Grundlegende Verwendung</h2><p>Beginnen wir mit einem einfachen Beispiel, um zu verstehen, wie der Ruby-Filter funktioniert.</p><h3>Konfigurieren des Ruby-Filters</h3><p>Wenn Sie eine Logstash-Pipeline erstellen, sollten Sie die Konfigurationsdatei im Verzeichnis <code>/etc/logstash/conf.d</code> ablegen. Alternativ können Sie die Option <code>-f</code> verwenden, um beim manuellen Starten von Logstash den Pfad zur Konfigurationsdatei anzugeben, sodass Sie problemlos mit Ihren Pipelines experimentieren können.</p>$ ./bin/logstash -f /path/to/your_pipeline.conf<p>Die Konfigurationsdatei sollte die Dateiendung <code>.conf</code> haben.</p><p>Um den Ruby-Filter zu verwenden, definieren Sie einen <code>ruby</code> -Filter im Filterabschnitt Ihrer Logstash-Pipeline-Konfigurationsdatei (*.conf). Hier ein einfaches Beispiel:</p>filter {
  ruby {
    code =&gt; "
      event.set('new_field', 'Hello from Ruby!')
    "
  }
}<p>Dieser Inline-Ruby-Filter definiert eine Ruby-Filterinstanz innerhalb Ihrer Logstash-Konfiguration. Der Parameter <code>code</code> stellt das Inline-Ruby-Skript bereit, das Logstash für jedes von diesem Filter verarbeitete Ereignis ausführt. Innerhalb dieses Skripts gibt es eine <code>event</code> Variable, die das Ereignis selbst repräsentiert. Das Ereignisobjekt enthält die Originaldaten, die an Logstash gesendet wurden, sowie alle zusätzlichen Felder, die während der Filterphasen von Logstash erstellt wurden. Sie können auf diese Felder über die Logstash Event API zugreifen, zum Beispiel über <code>event.get()</code> und <code>event.set()</code>. In diesem Beispielcode hat <code>event.set('new_field', 'Hello from Ruby!')</code> ein neues Feld mit dem Namen <code>new_field</code> auf den Zeichenkettenwert <code>Hello from Ruby!</code> gesetzt. Sie können bei Bedarf weiteren Code in diesen <code>code</code> -Block einfügen.</p><p>Beachten Sie, dass dieses <code>event</code> -Objekt kein gewöhnliches Ruby-Hash-Objekt ist, obwohl es als Datencontainer vom Typ Schlüssel-Wert fungiert. In <a href="https://www.elastic.co/docs/reference/logstash/event-api">dieser offiziellen Dokumentation</a> erfahren Sie mehr über die Event-API.</p><h3>Ruby-Skript auslagern</h3><p>Für einfache Transformationen ist Inline-Ruby-Code praktisch. Für komplexe Logik oder wiederverwendbare Funktionen empfiehlt es sich jedoch, den Code in ein externes Ruby-Skript auszulagern. Dies verbessert die Wartbarkeit und sorgt für eine saubere Logstash-Pipeline-Konfiguration.</p><p>Zuerst erstellen Sie ein Ruby-Skript und speichern es unter dem Namen <code>my_ruby_script.rb</code>. Das Skript muss eine <code>filter</code> Methode definieren, die das Ereignis verarbeitet. Es benötigt ein Ereignisobjekt als Argument, das das aktuell verarbeitete Ereignis repräsentiert. Die Methode <code>filter</code> muss ein Array von Ereignissen zurückgeben, die ausgelöst werden sollen. Um das Ereignis zu verwerfen, geben Sie ein leeres Array zurück.</p><p>Das folgende Skript liest beispielsweise das Feld <code>message</code> , berechnet seine Länge und speichert das Ergebnis in einem neuen Feld namens <code>message_length</code>.</p>def register(params)
  # This method is called when the plugin is loaded.
  # You can use it to initialize any instance variables or perform setup tasks.
end

def filter(event)
  message = event.get('message')

  if message
    event.set('message_length', message.length)
  end

  return [event]
end<p>Als Nächstes muss die Ruby-Filterkonfiguration so eingestellt werden, dass sie mit der Option <code>path</code> auf das Skript verweist. Dies weist Logstash an, das externe Skript zu laden und auszuführen. Bei der Verwendung externer Skripte muss sichergestellt werden, dass die Datei existiert und über die korrekten Berechtigungen verfügt.</p>filter {
  ruby {
    path =&gt; "/path/to/my_ruby_script.rb"
  }
}<p>Nun wird jedes Ereignis an die Methode <code>filter</code> in <code>my_ruby_script.rb</code> übergeben und von dieser verarbeitet.</p><p>Dieser Ansatz hilft Ihnen, komplexe Logik effektiver zu handhaben und erleichtert so das Testen, Debuggen und Wiederverwenden Ihres Ruby-Codes.</p><h2>Erweiterte Nutzung</h2><p>In diesem Abschnitt werden wir einige fortgeschrittene Beispiele für die Verwendung des Ruby-Filters in Logstash untersuchen. Anhand dieser Beispiele wird demonstriert, wie man Datentransformationen durchführt, Ereignisse anreichert und benutzerdefinierte Logik mit Ruby implementiert.</p><h3>Manipulation verschachtelter Datenstrukturen</h3><p>Ein Logstash-Ereignis ist die zentrale Datenstruktur, die von Logstash verarbeitet wird. Es kann verschiedene Felder enthalten, darunter auch verschachtelte Datenstrukturen wie Arrays und Hashes. Der Ruby-Filter ermöglicht Ihnen die einfache Bearbeitung dieser verschachtelten Strukturen.</p><p>Der Ruby-Filter kann verschachtelte Datenstrukturen wie Hashes und Arrays verarbeiten und ermöglicht es Ihnen, Felder innerhalb dieser Strukturen zu ändern oder hinzuzufügen. Dies ist hilfreich beim Umgang mit komplexen Datenformaten wie JSON.</p>input {
  generator {
    lines =&gt; [
      '{"nested": {"key1": "value1", "key2": "value2"}}'
    ]
    count =&gt; 1
    codec =&gt; "json"
    ecs_compatibility =&gt; "disabled"
  }
}

filter {
  ruby {
    code =&gt; "
      nested_data = event.get('nested')

      if nested_data.is_a?(Hash)
        nested_data['key3'] = 'value3'
        event.set('nested', nested_data)
      end
    "
  }
}

output {
  stdout { codec =&gt; rubydebug }
}<p>Dieses Beispiel enthält ein verschachteltes JSON-Objekt in den Eingabedaten. Der Ruby-Filter modifiziert die verschachtelten Daten, indem er ein neues Schlüssel-Wert-Paar hinzufügt. Diese Art der Manipulation von verschachtelten Daten ist mit den Standard-Logstash-Filtern nicht möglich, wodurch der Ruby-Filter eine praktische Option für komplexe Datenstrukturen darstellt.</p><h3>Teile ein einzelnes Ereignis in mehrere Ereignisse auf</h3><p>Ruby-Filter können auch verwendet werden, um ein einzelnes Ereignis in mehrere Ereignisse aufzuteilen. Dies ist nützlich, wenn Sie ein einzelnes Ereignis haben, das ein Array von Elementen enthält, und Sie für jedes Element ein separates Ereignis erstellen möchten.</p><p>Beachten Sie, dass weder die Ingest-Pipeline von Elasticsearch noch die Prozessoren von Beats/Elastic Agent das Aufteilen von Ereignissen unterstützen. Dies ist einer der überzeugendsten Anwendungsfälle für Logstash.</p><h4>Mit geteiltem Filter</h4><p>Mit dem Filter <code>split</code> können Sie ein Ereignis anhand eines bestimmten Feldes in mehrere Ereignisse aufteilen. Wenn Sie jedoch während der Aufteilung zusätzliche Transformationen oder Logik durchführen müssen, können Sie den Ruby-Filter in Kombination mit dem Split-Filter verwenden.</p><p>Im folgenden Beispiel haben wir einen RSS-Feed als einzeiligen XML-Text. Es enthält mehrere <code>&lt;item&gt;</code> -Elemente. Der Ruby-Filter dient dazu, die <code>&lt;item&gt;</code> -Elemente aus dem XML zu extrahieren und in einem neuen Feld namens <code>items</code> zu speichern. Anschließend wird der Split-Filter verwendet, um das Ereignis anhand des Feldes <code>items</code> in mehrere Ereignisse aufzuteilen.</p>input {
  generator {
    lines =&gt; [
      '&lt;rss version="2.0"&gt;&lt;channel&gt;&lt;title&gt;Sample RSS&lt;/title&gt;&lt;item&gt;&lt;title&gt;Article 1&lt;/title&gt;&lt;link&gt;http://example.com/1&lt;/link&gt;&lt;description&gt;Desc 1&lt;/description&gt;&lt;/item&gt;&lt;item&gt;&lt;title&gt;Article 2&lt;/title&gt;&lt;link&gt;http://example.com/2&lt;/link&gt;&lt;description&gt;Desc 2&lt;/description&gt;&lt;/item&gt;&lt;/channel&gt;&lt;/rss&gt;'
    ]
    count =&gt; 1
    codec =&gt; "plain"
    ecs_compatibility =&gt; "disabled"
  }
}

filter {
  xml {
    source =&gt; "message"
    target =&gt; "rss"
    store_xml =&gt; true
    force_array =&gt; false
  }
  ruby {
    code =&gt; "event.set('items', event.get('[rss][channel][item]')) if event.get('[rss][channel][item]')"
  }
  split {
    field =&gt; "items"
  }
  ruby {
    code =&gt; "
      item = event.get('items')
      event.set('title', item['title']) if item['title']
      event.set('link', item['link']) if item['link']
      event.set('description', item['description']) if item['description']
    "
  }
  mutate {
    remove_field =&gt; ["@timestamp", "@version", "sequence", "host", "event", "message", "rss", "items"]
  }
}

output {
  stdout { codec =&gt; rubydebug }
}<p>Die Ausgabe lautet wie folgt:</p>{
          "title" =&gt; "Article 1",
           "link" =&gt; "http://example.com/1",
    "description" =&gt; "Desc 1"
}
{
          "title" =&gt; "Article 2",
           "link" =&gt; "http://example.com/2",
    "description" =&gt; "Desc 2"
}<p>Wie Sie vielleicht bemerkt haben, ist der <code>ruby</code> -Filter in diesem Fall nicht unbedingt erforderlich. Mit dem Filter <code>split</code> kann das Ereignis anhand des Feldes <code>items</code> in mehrere Ereignisse aufgeteilt werden, und mit dem Filter <code>mutate</code> können unnötige Felder entfernt werden. Wenn Sie jedoch während der Aufteilung zusätzliche Transformationen oder Logik durchführen müssen, können Sie den Ruby-Filter verwenden.</p><h4>Verwenden Sie das Inline-Ruby-Skript.</h4><p>Sie können auch ein Inline-Ruby-Skript verwenden, um ein einzelnes Ereignis in mehrere Ereignisse aufzuteilen, indem Sie die Methode <code>event.clone</code> und die Methode <code>new_event_block variable</code> verwenden, z. B. <code>new_event_block.call(new_event)</code>. Dies ermöglicht es Ihnen, neue Ereignisse auf Basis des ursprünglichen Ereignisses zu erstellen und dabei dessen Daten zu erhalten.</p><p>Hier ist ein Beispiel, wie man den Ruby-Filter verwendet, um ein einzelnes Ereignis in mehrere Ereignisse aufzuteilen. Eingabe und Ausgabe sind die gleichen wie im vorherigen Beispiel.</p>filter {
  xml {
    source =&gt; "message"
    target =&gt; "rss"
    store_xml =&gt; true
    force_array =&gt; false
  }
  ruby {
    code =&gt; "
      items = event.get('[rss][channel][item]')
      if items.is_a?(Array)
        items.each do |item|
          new_event = event.clone
          new_event.set('title', item['title'])
          new_event.set('link', item['link'])
          new_event.set('description', item['description'])
          new_event_block.call new_event
        end
        event.cancel
      elsif items.is_a?(Hash)
        event.set('title', items['title'])
        event.set('link', items['link'])
        event.set('description', items['description'])
      end
    "
  }
  mutate {
    remove_field =&gt; ["@timestamp", "@version", "sequence", "host", "event", "message", "rss", "items"]
  }
}<h4>Externes Ruby-Skript verwenden</h4><p>Alternativ können Sie ein externes Ruby-Skript verwenden, um ein einzelnes Ereignis in mehrere Ereignisse aufzuteilen.</p><p>Konfigurationsdatei:</p>filter {
  xml {
    source =&gt; "message"
    target =&gt; "rss"
    store_xml =&gt; true
    force_array =&gt; false
  }
  ruby {
    path =&gt; "path/to/ruby/split_event.rb"
  }
  mutate {
    remove_field =&gt; ["@timestamp", "@version", "sequence", "host", "event", "message", "rss", "items"]
  }
}<p>Das Ruby-Skript muss als <code>split_event.rb</code> externalisiert werden:</p>def filter(event)
  items = event.get('[rss][channel][item]')
  events = []
  if items.is_a?(Array)
    items.each do |item|
      new_event = event.clone
      new_event.set('title', item['title'])
      new_event.set('link', item['link'])
      new_event.set('description', item['description'])
      events &lt;&lt; new_event
    end
    return events
  elsif items.is_a?(Hash)
    event.set('title', items['title'])
    event.set('link', items['link'])
    event.set('description', items['description'])
    return [event]
  else
    return []
  end
end<p>Denken Sie daran, dass die Methode <code>filter</code> ein Array von Ereignissen zurückgeben muss. Sie können mehrere Ereignisse zurückgeben, indem Sie ein eingehendes Ereignisobjekt klonen und die Ergebnisse dem Array hinzufügen, oder Sie können ein einzelnes Ereignis als Array mit einem Element zurückgeben.</p>return events
# or
# return [event]<p>Dies ermöglicht es Ihnen, ein einzelnes Ereignis in mehrere Ereignisse aufzuteilen.</p><h3>Führe externe Befehle aus und analysiere deren Ausgabe.</h3><p>Das Logstash exec input-Plugin ermöglicht die Ausführung externer Befehle, deren Ausgabe ein Logstash-Ereignis darstellt. Die Ausgabe des Befehls wird im Feld <code>message</code> des Ereignisses gespeichert.</p><p>Normalerweise sind die Ausgaben von Systembefehlen für Menschen lesbar, aber nicht als JSON oder in anderen Formaten strukturiert, die Logstash problemlos parsen kann. Um dies zu handhaben, können Sie den Ruby-Filter verwenden, um die Ausgabe zu analysieren und die Informationen daraus zu extrahieren.</p><p>Hier ist ein Beispiel für die Verwendung des <code>exec</code> -Input-Plugins zur Ausführung des <code>ps -ef</code> -Befehls, der alle laufenden Prozesse auf einem Unix-ähnlichen System auflistet. Die Ausgabe wird vom Ruby-Filter analysiert, um relevante Informationen über jeden Prozess zu extrahieren.</p>input {
  exec {
    command =&gt; "ps -ef"
    interval =&gt; 60
  }
}

filter {
  ruby {
    code =&gt; '
      processes = []
      lines = event.get("message").split("\n")  
      lines.each_with_index do |line, index|
        # Skip header line and empty lines
        next if index == 0 || line.strip.empty?
        entry = nil
        
        # Use regex to match the ps -ef output format more flexibly
        # This pattern accounts for variable spacing and different time formats
        if line =~ /^\s*(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+([\d:]+\.?\d*)\s+(.+)$/
          uid, pid, ppid, c, stime, tty, time, cmd = $1, $2, $3, $4, $5, $6, $7, $8
          
          entry = {
            "UID" =&gt; uid,
            "PID" =&gt; pid,
            "PPID" =&gt; ppid,
            "C" =&gt; c,
            "STIME" =&gt; stime,
            "TTY" =&gt; tty,
            "TIME" =&gt; time,
            "CMD" =&gt; cmd.strip
          }
        elsif line =~ /^\s*(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.+)$/
          # Fallback pattern for lines that might not match the exact format
          # Split the remaining part more carefully
          uid, pid, ppid, c, remainder = $1, $2, $3, $4, $5
          
          # Split remainder into STIME, TTY, TIME, CMD
          parts = remainder.strip.split(/\s+/, 4)
          if parts.length &gt;= 4
            stime, tty, time, cmd = parts[0], parts[1], parts[2], parts[3]
            
            entry = {
              "UID" =&gt; uid,
              "PID" =&gt; pid,
              "PPID" =&gt; ppid,
              "C" =&gt; c,
              "STIME" =&gt; stime,
              "TTY" =&gt; tty,
              "TIME" =&gt; time,
              "CMD" =&gt; cmd
            }
          end
        end
        if entry &amp;&amp; entry["UID"] == "0"
          original_line = line.strip
          entry["original_line"] = original_line if original_line.length &gt; 0
          processes.push(entry)
        end
      end
      event.set("processes", processes)
      event.remove("message")
      event.remove("event")
    '
  }
}

output {
  stdout { codec =&gt; rubydebug }
}<p>Dieses Beispiel verwendet das <code>exec</code> -Input-Plugin, um den <code>ps -ef</code> -Befehl alle 60 Sekunden auszuführen. Der Ruby-Filter verarbeitet die Ausgabe und extrahiert relevante Felder wie UID, PID, PPID, CPU-Auslastung (C), Startzeit (STIME), TTY, Gesamt-CPU-Zeit (TIME) und den ausgeführten Befehl (CMD). Auf meiner macOS-Umgebung funktioniert es einwandfrei, aber möglicherweise müssen Sie die Regex-Muster an das Ausgabeformat des Befehls <code>ps -ef</code> auf Ihrem System anpassen.</p><h3>Verwenden Sie integrierte Bibliotheken</h3><p>Das Ruby-Filter-Plugin ermöglicht die Verwendung integrierter Ruby-Bibliotheken, was für verschiedene Aufgaben sehr nützlich sein kann. Beispielsweise können Sie die <code>json</code> -Bibliothek zum Parsen von JSON-Zeichenketten oder die <code>date</code> -Bibliothek zum Bearbeiten von Datumsangaben verwenden.</p><p>Hier ist ein Beispiel für die Verwendung der <code>json</code> -Bibliothek zum Parsen einer in einem Feld gespeicherten JSON-Zeichenkette:</p>require 'json'

def filter(event)
  json_string = event.get('message')
  parsed_json = JSON.parse(json_string)
  event.set('parsed_json', parsed_json)
  return [event]
end<p>Um zu vermeiden, dass die Bibliothek jedes Mal neu geladen werden muss, sollten Sie Ihren Ruby-Code auslagern, damit Sie die <code>require</code> -Anweisung am Anfang Ihres Ruby-Filterskripts verwenden können. Dadurch wird die Bibliothek einmalig geladen und steht Ihnen anschließend in Ihrem Skript zur Verfügung.</p><p>Um zu überprüfen, welche Bibliotheken in Ihrer Umgebung verfügbar sind, können Sie die integrierten Bibliotheken auflisten, indem Sie den folgenden Code im Ruby-Filter ausführen:</p>Gem.loaded_specs.sort_by { |name, _| name }.each do |name, spec|
  puts "#{name}: #{spec.version}"
end<p><strong>Hinweis: </strong>Die integrierten Bibliotheken werden von Logstash nicht offiziell unterstützt, und ihr Verhalten kann sich ändern oder sie sind in zukünftigen Versionen möglicherweise nicht mehr verfügbar. Die Benutzung erfolgt auf eigene Gefahr.</p><h2>Fazit</h2><p>Mit dem Logstash Ruby-Filter können Sie die Funktionen Ihrer Logstash-Pipelines anpassen und erweitern. In diesem Beitrag haben wir die Grundlagen der Verwendung des Ruby-Filters behandelt und fortgeschrittene Anwendungsbeispiele vorgestellt.</p><p>Durch die Nutzung des Ruby-Filters können Sie komplexe Datenverarbeitungsaufgaben bewältigen, die benutzerdefinierte Logik oder fortgeschrittene Manipulationen erfordern. Egal ob Sie mit verschachtelten Datenstrukturen arbeiten, Ereignisse aufteilen oder komplexen/unstrukturierten Text in strukturiertes JSON parsen und konvertieren, der Ruby-Filter bietet die Flexibilität, Ihre spezifischen Anforderungen zu erfüllen.</p><p>Wir hoffen, dass Ihnen dieser Leitfaden das Wissen und die Inspiration vermittelt hat, das volle Potenzial des Logstash Ruby-Filters auszuschöpfen. Viel Spaß beim Skripten!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/ruby-scripting-logstash</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/ruby-scripting-logstash</guid>
    <category><![CDATA[Index-Daten]]></category>
    <category><![CDATA[Ruby]]></category>
    <dc:creator><![CDATA[Dai Sugimori]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt503d18396642e73e/6a17f62aaf47b68527cde121/b1bcd63c033ccbde102c20ba3085f165f9289a71-1600x1000.png" length="0" type="image/png"/>
    <pubDate>Tue, 24 Jun 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Anzeigen von Feldern in einem Elasticsearch-Index]]></title>
    <description><![CDATA[Untersuchung von Techniken zur Darstellung von Feldern in einem Elasticsearch-Index.
]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel werden wir erläutern, wie Felder in einem Elasticsearch-Index angezeigt werden. Dies kann hilfreich sein, um die Struktur Ihrer Daten zu verstehen, bestimmte Felder zu identifizieren und Probleme zu beheben. Wir werden folgende Themen behandeln:</p><ol><li><p><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#1.-using-the--mapping-api-to-retrieve-field-information">Verwendung der </a><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#1.-using-the--mapping-api-to-retrieve-field-information"><code>_mapping</code></a><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#1.-using-the--mapping-api-to-retrieve-field-information"> API zum Abrufen von Feldinformationen</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#2.-using-the--search-api-to-display-field-values">Verwendung der </a><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#2.-using-the--search-api-to-display-field-values"><code>_search</code></a><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#2.-using-the--search-api-to-display-field-values"> API zum Anzeigen von Feldwerten</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#3.-filtering-fields-using-the-fields-parameter">Filtern von Feldern mithilfe des </a><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#3.-filtering-fields-using-the-fields-parameter"> Parameters</a><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#3.-filtering-fields-using-the-fields-parameter"><code>fields</code></a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index#4.-displaying-nested-fields">Verschachtelte Felder anzeigen</a></p></li></ol><h2>1. Verwendung der _mapping-API zum Abrufen von Feldinformationen</h2><p>Die <code>_mapping</code> API ermöglicht es Ihnen, die Mapping-Definition für einen oder mehrere <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-index/">Indizes</a> abzurufen. Dies umfasst Informationen über die Felder, ihre Datentypen und weitere Eigenschaften. Um die Zuordnung für einen bestimmten Index abzurufen, verwenden Sie die folgende Anfrage:</p>GET /&lt;index_name&gt;/_mapping<p>Wenn Sie beispielsweise einen Index mit dem Namen <code>my_index</code> haben, können Sie dessen Zuordnung mit der folgenden Anfrage abrufen:</p>GET /my_index/_mapping<p>Die Antwort enthält die Mapping-Definition für den Index, die Informationen über die Felder und deren Eigenschaften enthält.</p><p>Es ist auch möglich, die Zuordnung eines bestimmten Feldes abzurufen. Dies kann nützlich sein, wenn Ihre Kartierung recht umfangreich ist und Sie sich nur auf ein bestimmtes Feld konzentrieren möchten. Um die Zuordnung eines bestimmten Feldes abzurufen, verwenden Sie die folgende Anfrage:</p>GET /my_index/_mapping/field/my_field<p>Sie können die Zuordnungen mehrerer Felder auch abrufen, indem Sie deren Namen durch Kommas trennen, wie in der folgenden Anfrage:</p>GET /my_index/_mapping/field/my_field_1,my_field_2,my_field_3<h2>2. Verwenden der _search-API zum Anzeigen von Feldwerten</h2><p>Um die Werte von Feldern in einem Elasticsearch-Index anzuzeigen, können Sie die <code>_search</code> API verwenden. Standardmäßig gibt die <code>_search</code> API das Feld <code>_source</code> zurück, welches das ursprüngliche JSON-Dokument enthält, das indiziert wurde. Um nur bestimmte Felder anzuzeigen, können Sie den Parameter <code>_source</code> in der Suchanfrage verwenden.</p><p>Hier ist ein Beispiel für eine Suchanfrage, die die Werte der Felder <code>title</code> und <code>author</code> für Dokumente im Index <code>my_index</code> zurückgibt:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "_source": ["title", "author"]
}<p>In diesem Beispiel gibt der Parameter <code>_source</code> die zurückzugebenden Felder an.</p><h2>3. Filtern von Feldern mithilfe des Parameters „fields“</h2><p>Sie können auch den Parameter <code>fields</code> verwenden, um die in der Suchantwort zurückgegebenen Felder zu filtern. Dies kann nützlich sein, wenn Sie nur bestimmte Felder benötigen und die Größe der Antwort reduzieren möchten. Der Parameter <code>fields</code> akzeptiert ein Array von Feldnamen oder Platzhaltermustern.</p><p>Um beispielsweise nur die Felder <code>title</code> und <code>author</code> für Dokumente im Index <code>my_index</code> zurückzugeben, können Sie die folgende Suchanfrage verwenden:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "fields": ["title", "author"],
  "_source": false
}<p>Beachten Sie, dass der Parameter <code>_source</code> auf false gesetzt ist, um das Quelldokument nicht zurückzugeben.</p><p>Um alle Felder mit dem Datentyp <code>text</code> zurückzugeben, können Sie ein Wildcard-Muster wie dieses verwenden:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "fields": ["*.text"],
  "_source": false
}<h2>4. Anzeigen verschachtelter Felder</h2><p>Wenn Ihr Index verschachtelte Felder enthält, können Sie die Punktnotation verwenden, um den Pfad des verschachtelten Feldes im Parameter <code>fields</code> anzugeben. Wenn Sie beispielsweise ein verschachteltes Feld mit dem Namen <code>address.city</code> haben, können Sie es wie folgt in die Suchergebnisseinlösung einbinden:</p>GET /my_index/_search
{
  "query": {
    "match_all": {}
  },
  "fields": ["title", "author", "address.city"],
  "_source": false
}<p>In diesem Beispiel enthält die Suchergebnisseinsendung die Werte der Felder <code>title</code>, <code>author</code> und <code>address.city</code> .</p><h2>Fazit</h2><p>Zusammenfassend lässt sich sagen, dass die Anzeige von Feldern in einem Elasticsearch-Index durch die Verwendung der <code>_mapping</code> -API zum Abrufen von Feldinformationen und der <code>_search</code> -API zum Anzeigen von Feldwerten erreicht werden kann. Sie können die in der Suchantwort zurückgegebenen Felder entweder mit den Parametern <code>_source</code> oder <code>fields</code> filtern und verschachtelte Felder mit der Punktnotation anzeigen. Mithilfe dieser Techniken können Sie die Struktur Ihrer Daten verstehen, bestimmte Felder identifizieren und Probleme beheben.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/displaying-fields-in-an-elasticsearch-index</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3a1fcc771a2504e5/6a17f817abe0f23038dfebca/fa386d7bbaeab6855e62897ace8d7dca91a060b4-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 26 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch-Felder von der Indizierung ausschließen]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie Elasticsearch konfigurieren, um Felder auszuschließen, die Hauptgründe für das Ausschließen von Feldern aus dem Indizieren und die zu befolgenden Best Practices.]]></description>
    <content:encoded><![CDATA[<p>In Elasticsearch bezeichnet Indexierung den Prozess des Speicherns und Organisierens von Daten, sodass diese leicht durchsuchbar sind. Während die Indizierung aller Felder eines Dokuments in manchen Fällen sinnvoll sein kann, gibt es Situationen, in denen man bestimmte Felder von der Indizierung ausschließen möchte. Dies kann dazu beitragen, die Leistung zu verbessern, die Speicherkosten zu senken und die Gesamtgröße Ihres Elasticsearch-Index zu minimieren.</p><p>In diesem Artikel werden wir die Gründe für den Ausschluss von Feldern aus der Indizierung, die Konfiguration von Elasticsearch zum Ausschluss bestimmter Felder und einige bewährte Vorgehensweisen dabei erläutern.</p><h2>Gründe für den Ausschluss von Feldern aus der Indizierung</h2><ol><li><p><strong>Leistung: </strong>Die Indizierung aller Felder in einem Dokument kann zu längeren Indizierungszeiten und einer langsameren Suchleistung führen. Durch den Ausschluss von Feldern, die für die Suche oder Aggregation nicht erforderlich sind, können Sie die Gesamtleistung Ihres Elasticsearch-Clusters verbessern.</p></li><li><p><strong>Speicherplatz: </strong>Das Indizieren von Feldern benötigt Speicherplatz. Durch das Ausschließen von Feldern, die für die Suche oder Aggregation nicht benötigt werden, können die Speicheranforderungen Ihres Elasticsearch-Clusters reduziert werden.</p></li><li><p><strong>Indexgröße: </strong>Die Größe eines Elasticsearch-Index steht in direktem Zusammenhang mit der Anzahl der indizierten Felder. Durch den Ausschluss unnötiger Felder können Sie die Größe Ihres Index minimieren, was zu einer schnelleren Such- und Indexierungsleistung führen kann.</p></li></ol><h2>Elasticsearch so konfigurieren, dass Felder ausgeschlossen werden</h2><p>Um ein Feld von der Indizierung in Elasticsearch auszuschließen, können Sie die „index“-Eigenschaft in der Feldzuordnung verwenden. Wenn die Eigenschaft „index“ auf „false“ gesetzt wird, wird Elasticsearch das Feld nicht indizieren, und es ist weder durchsuchbar noch für Aggregationen verfügbar.</p><p>Hier ist ein Beispiel dafür, wie man ein Feld mithilfe des Elasticsearch-Mappings von der Indizierung ausschließt:</p>PUT /my_index
{
  "mappings": {
    "properties": {
      "field_to_exclude": {
        "type": "text",
        "index": false
      }
    }
  }
}<p>In diesem Beispiel erstellen wir einen neuen Index namens „my_index“ mit einem einzigen Feld namens „field_to_exclude“. Indem wir die Eigenschaft „index“ auf „false“ setzen, weisen wir Elasticsearch an, dieses Feld nicht zu indizieren. Das Feld wird jedoch im Quelldokument weiterhin verfügbar sein.</p><h2>Bewährte Verfahren zum Ausschließen von Feldern von der Indizierung</h2><ol><li><p><strong>Analysieren Sie Ihre Daten: </strong>Bevor Sie Felder von der Indizierung ausschließen, ist es unerlässlich, Ihre Daten zu analysieren und zu verstehen, welche Felder für die Suche und Aggregation notwendig sind. Dies wird Ihnen helfen, fundierte Entscheidungen darüber zu treffen, welche Felder ausgeschlossen werden sollen.</p></li><li><p><strong>Testen Sie Ihre Änderungen: </strong>Wenn Sie Felder von der Indizierung ausschließen, ist es unerlässlich, Ihre Änderungen zu testen, um sicherzustellen, dass Ihre Such- und Aggregationsfunktionen weiterhin wie erwartet funktionieren. Dies kann Ihnen helfen, unerwartete Probleme oder Leistungsstörungen zu vermeiden.</p></li><li><p><strong>Leistungsüberwachung:</strong> Nachdem Sie Felder von der Indizierung ausgeschlossen haben, sollten Sie die Leistung Ihres Elasticsearch-Clusters überwachen, um sicherzustellen, dass Ihre Änderungen den gewünschten Effekt erzielt haben. Dies kann Ihnen dabei helfen, eventuell erforderliche zusätzliche Optimierungen zu identifizieren.</p></li><li><p><strong>Quellfilterung nutzen:</strong> Wenn Sie ein Feld in Elasticsearch speichern müssen, es aber nicht durchsuchbar oder für Aggregationen verfügbar sein soll, sollten Sie die Quellfilterung in Betracht ziehen. Dies ermöglicht es Ihnen, das Feld im Feld _source zu speichern, es aber vom Index auszuschließen.</p></li></ol><h2>Fazit</h2><p>Das Ausschließen von Feldern von der Indizierung in Elasticsearch kann die Leistung verbessern, die Speicherkosten senken und die Gesamtgröße Ihres Index minimieren. Durch eine sorgfältige Analyse Ihrer Daten und das Verständnis, welche Felder für die Suche und Aggregation notwendig sind, können Sie fundierte Entscheidungen darüber treffen, welche Felder ausgeschlossen werden sollten. Testen Sie Ihre Änderungen stets und überwachen Sie die Leistung Ihres Elasticsearch-Clusters, um sicherzustellen, dass Ihre Optimierungen den gewünschten Effekt erzielen.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/excluding-elasticsearch-fields-from-indexing</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/excluding-elasticsearch-fields-from-indexing</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt399bcc5a2e55bfe0/6a1708b45091684557e1ba3c/3aa0b481994d2445ba979d3c79fff64c5ee6676a-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 12 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Indexvorlagen in Elasticsearch: Wie man zusammensetzbare Vorlagen verwendet]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie in Elasticsearch zusammensetzbare und komponentenbasierte Indexvorlagen erstellen, um konsistente Mappings sicherzustellen und die Indexkonfiguration zu automatisieren.]]></description>
    <content:encoded><![CDATA[<p>Ein Elasticsearch-Index kann über Mapping, Einstellungen und Aliase konfiguriert werden: </p><ul><li><p>Mapping-Definitionen legen das Datenschema fest.</p></li><li><p>In den Einstellungen werden die Shard-Größe und die Aktualisierungsraten festgelegt. </p></li><li><p>Aliase werden verwendet, um dem Index alternative Namen zu geben.</p></li></ul><p>Wenn wir ein Dokument zum ersten Mal indexieren oder einen leeren Index mithilfe der Create Index API erstellen, wird der Index mit Standardeinstellungen, ohne Datenschema und ohne Aliase erstellt. Diese Standardeinstellungen funktionieren in Entwicklungs- und Testumgebungen recht gut, aber für Produktionsumgebungen müssen wir unsere Indizes möglicherweise anpassen.</p><p>Die Verwendung der Standardzuordnungen und -einstellungen in der Produktionsumgebung kann zu einer schlechten Indexierungs- und Suchleistung führen. Das manuelle Erstellen von Indizes ist ein mühsamer und zeitaufwändiger Prozess. Die Neuerstellung solcher Indizes in jeder Umgebung ist besonders unpraktisch, wenn wir ein aufwendiges Mapping-Schema sowie benutzerdefinierte Einstellungen und Aliase haben.</p><p>Glücklicherweise stellt Elasticsearch uns ein Werkzeug zur Verfügung, mit dem wir beim Erstellen von Indizes automatisch eine vordefinierte Konfiguration in Form von <em>Indexvorlagen</em> anwenden können <em>.</em></p><h2>Indexvorlagen</h2><p>Indexvorlagen ermöglichen es uns, Indizes mit benutzerdefinierter Konfiguration zu erstellen. Ein Index kann die Konfiguration aus diesen Vorlagen abrufen, beispielsweise eine festgelegte Anzahl von Shards und Replikaten oder Feldzuordnungen, während seiner Instanziierung. Es wird eine Vorlage mit einem Namensmuster und einigen Konfigurationseinstellungen definiert. Wenn der Name des Index mit dem Namensmuster der Vorlage übereinstimmt, wird der neue Index mit der in der Vorlage definierten Konfiguration erstellt.</p><p>Elasticsearch hat in Version 7.8 seine Template-Funktionalität mit zusammensetzbaren Templates verbessert. Diese neuere Version bietet wesentlich mehr wiederverwendbare Indexvorlagen, wie in diesem Artikel gezeigt wird.</p><h3>Arten von Indexvorlagen</h3><p>Indexvorlagen lassen sich in zwei Kategorien einteilen:</p><ul><li><p><strong>Indexvorlagen (oder zusammensetzbare Indexvorlagen)</strong>: Die zusammensetzbaren Indexvorlagen können entweder allein existieren oder aus keiner oder mehreren Komponentenvorlagen zusammengesetzt sein (siehe die zweite Kategorie).</p></li><li><p><strong>Komponentenvorlagen:</strong> Die Komponentenvorlage ist eine <em>wiederverwendbare</em> Vorlage, die die erforderliche Konfiguration definiert. Üblicherweise wird erwartet, dass die Komponentenvorlage mit einer Indexvorlage verknüpft ist. Jede der Komponentenvorlagen kann mit einer oder mehreren Indexvorlagen verknüpft werden. </p></li></ul><p>Wie Sie im Bild unten sehen können, teilen sich die Indexvorlagen A und B Komponentenvorlagen (in diesem Fall nur eine – Vorlage 3). Eine Indexvorlage kann aus keiner oder mehreren Komponentenvorlagen bestehen, und jede der Komponentenvorlagen kann keiner oder mehreren Indexvorlagen zugeordnet sein. Beide Arten von Vorlagen können eigenständig existieren, jedoch sind Komponentenvorlagen nur dann nützlich, wenn sie an eine Indexvorlage angehängt werden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7fca132e0eb86c50/6a17f5b7ec0f8982a65a678c/96c0aac29d3992e54a79be34e14cf909e0ca2ea9-1202x556.png" alt="Indexvorlagen in Elasticsearch und deren Komponenten." /><p>Die Grundidee besteht darin, einen Katalog von Komponentenvorlagen zu entwickeln, die eine Organisation für verschiedene Zwecke nutzen kann (z. B. die verschiedenen Komponentenvorlagen für einzelne Umgebungen festlegen) und diese über die zusammensetzbaren Indexvorlagen verschiedenen Indizes zuzuordnen.</p><h2>Wie man zusammensetzbare (Index-)Vorlagen erstellt</h2><p>Elasticsearch bietet einen _index_template-Endpunkt zur Verwaltung von Indexvorlagen. Der Benutzer gibt in dieser Vorlage alle erforderlichen Zuordnungen, Einstellungen und Aliase sowie ein Indexnamensmuster an. Betrachten wir ein Beispiel für die Erstellung einer Vorlage für eine Microservice-Anwendung <em>namens customer-order-service</em> , die für die Logik zur Auftragsgenerierung zuständig ist. </p><p>Nehmen wir an, unsere Anforderung ist es, eine Vorlage für Kundenbestellungen zu erstellen, die durch ein Muster mit Platzhaltern dargestellt wird: *orders. Diese Vorlage muss bestimmte Zuordnungen und Einstellungen enthalten, wie zum Beispiel das Feld order_date sowie Shard- und Replikatnummern.</p><p>Jeder Index, der bei seiner Erstellung mit dieser Vorlage übereinstimmt, erbt die in dieser Vorlage definierten Konfigurationen. Ein Index namens black_friday_orders beispielsweise hat das Feld order_date, die Anzahl der Shards ist auf 5 und die Anzahl der Replikate auf 2 festgelegt. Darüber hinaus erben <em>alle</em> aus dieser Vorlage erstellten Indizes auch einen einzigen <a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-alias/">Aliasnamen</a> ! Erstellen wir nun diese orders_template mit einem Indexmuster, das als *orders definiert ist, und einem Mapping-Schema, das aus einem einzigen Feld der_date mit dem vordefinierten Datumsformat dd-MM-yyyy besteht. Der folgende Code zeigt, wie diese Indexvorlage erstellt wird.</p>PUT _index_template/orders_template
{
  "index_patterns": ["*orders"],
  "priority": 300,
  "template": {
    "mappings": {
      "properties": {
        "order_date": {
          "type": "date",
          "format":"dd-MM-yyyy"
        }
      }
    },
    "settings":{
      "number_of_shards":5,
      "number_of_replicas":2
    },
    "aliases":{
      "all_orders":{}
    }
  }
}<p>Wenn Sie diese Abfrage in den Kibana DevTools ausführen, wird die Vorlage mit dem Indexmuster *orders zusammen mit dem vordefinierten Mapping, den Einstellungen und einem Alias erstellt. index_patterns ist ein Array von Übereinstimmungsmustern; jeder Index, der diesem Muster entspricht, leitet die Vorlagenkonfiguration ab. Sie können folgenden Befehl ausführen, um die gespeicherte Vorlage abzurufen, die unsere Aktionen wiederholen sollte:</p>GET _index_template/orders_template <p>Außerdem wird beim Erstellen des Vorlagenattributs, das in der Vorlage definiert ist, eine Priorität, eine positive Zahl, festgelegt: Jede Vorlage wird mit einer Priorität definiert, sodass etwaige Konflikte zwischen Änderungen aus verschiedenen Vorlagen durch Verwendung dieses Wertes aufgelöst werden, wobei dem Wert mit der höheren Priorität Vorrang eingeräumt wird. Wir werden uns weiter unten eingehender mit der Priorisierung von Vorlagen befassen.</p><h2>Erstellen eines Index mit der Vorlage</h2><p>Jetzt haben wir eine Vorlage – einen Bauplan für die Erstellung von Indizes – der nächste Schritt ist die Erstellung eines Indexes. Wenn der Name des Index mit dem angegebenen Muster übereinstimmt, werden die Vorlagenkonfigurationen automatisch angewendet. Um dies zu beweisen, erstellen wir, wie der folgende Code zeigt, einen brandneuen Index mit dem Namen: blackfriday_orders:</p>PUT blackfriday_orders<p>Da der Name des Index (blackfriday_orders) mit dem im Template definierten Namensmuster übereinstimmt (d. h. *orders), sollte der Index alle aus der Vorlage abgeleiteten Konfigurationen erhalten. Lassen Sie uns diesen neu erstellten Index abrufen und überprüfen, ob dies tatsächlich zutrifft, indem wir den folgenden Code ausführen:</p>GET blackfriday_orders<p>Dies sollte folgendes Ergebnis liefern:</p>{
  "blackfriday_orders" : {
    "aliases" : {
      "all_orders" : { }
    },
    "mappings" : {
      "properties" : {
        "order_date" : {
          "type" : "date",
          "format" : "dd-MM-yyyy"
        }
      }
    },
    "settings" : {
      "index" : {
         ...
        "number_of_shards" : "5",
        "number_of_replicas" : "2"
      }
    }
  }
}<p>Wie die Antwort zeigt, wurde die Konfiguration von blackfriday_orders aus der Vorlage übernommen. Wir können verschiedene Kombinationen der Indizes ausprobieren, die die Vorlagenkonfiguration erfolgreich übernehmen:</p>PUT blackfriday_orders
PUT americaorders
PUT cancelled--orders
PUT undefined101orders<p>Die folgenden Indizes werden die Konfiguration jedoch nicht übernehmen, da ihr Name nicht dem Muster entspricht:</p>PUT blackfriday_orders2
PUT open_orders_
PUT allorders_total<p>Wichtig zu beachten ist, dass alle von einer Vorlage abgeleiteten Indizes in diesem Fall denselben Alias haben – all_orders. Ein solcher Alias hat den Vorteil, dass wir einfach über diesen einen Alias anstatt über mehrere Indizes abfragen können.</p>GET blackfriday_orders,americaorders,undefined101orders/_search
GET all_orders/_search 
{
  "query": {
    "range": {
      "order_date": {
        "gte": "01-12-2021",
        "lte": "31-12-2021"
      }
    }
  }
}<p>Während wir eine Vorlage für *orders erstellen, wird erwartet, dass jeder übereinstimmende Index die Konfiguration der Vorlage übernimmt. In der Regel erstellen Teams, bewusst oder unbewusst, aus verschiedenen Gründen einige zusätzliche Vorlagen. Das bedeutet, dass der Indexname unter Umständen mit zwei verschiedenen Vorlagenmustern übereinstimmen kann! Elasticsearch muss entscheiden, welche der Konfigurationen aus diesen Vorlagen angewendet werden soll. Glücklicherweise lässt sich dieses Dilemma durch die Verwendung der Vorlagenpriorität lösen.</p><h2>Erstellung von Komponentenvorlagen</h2><p>Wir haben im vorangegangenen Teil dieses Artikels etwas über Indexvorlagen gelernt. Es gibt ein paar Nachteile bei der Erstellung der Vorlagen mit integrierter Konfiguration – einer dieser Nachteile ist, dass die Konfiguration nicht für andere Vorlagen exportiert werden kann. Wenn wir eine ähnliche Konfiguration wünschen, beispielsweise für kundenbezogene Vorlagen (*customers), müssen wir möglicherweise die gesamte Vorlage neu erstellen. Das bedeutet, dass wir in einer typischen Organisation Dutzende davon erstellen (und je nach Umgebung können noch einige weitere hinzukommen).</p><p>Da wir stets auf Wiederverwendbarkeit Wert legen, hat Elasticsearch die Templates unter Berücksichtigung der Wiederverwendbarkeit neu gestaltet. Die Komponentenvorlagen erfüllen diese Anforderung. Wenn Sie aus dem DevOps-Bereich kommen, besteht für Sie höchstwahrscheinlich die Anforderung, Indizes mit einer vordefinierten Konfiguration für jede Umgebung zu erstellen. Anstatt jede dieser Konfigurationen mühsam manuell anzuwenden, können Sie für jede Umgebung eine Komponentenvorlage erstellen.</p><p>Eine Komponentenvorlage ist nichts anderes als ein wiederverwendbarer Konfigurationsblock, mit dem wir weitere Indexvorlagen erstellen können. Beachten Sie, dass die Komponentenvorlagen nur dann einen Nutzen haben, wenn sie mit Indexvorlagen kombiniert werden. Sie werden über einen _component_template-Endpunkt bereitgestellt. Mal sehen, wie das alles zusammenpasst.</p><h3>Einstellungen in einer Indexvorlage</h3><p>Lassen Sie uns die Einstellungen, die wir zuvor in unserer Indexvorlage definiert haben, extrahieren und daraus eine Komponentenvorlage erstellen. Es wird erwartet, dass die settings_component_template fünf primäre Shards mit jeweils zwei Replikaten pro primärem Shard besitzt. Der erste Schritt besteht, wie die untenstehende Codeauflistung zeigt, darin, eine Komponentenvorlage mit dieser Konfiguration zu deklarieren und auszuführen.</p>PUT _component_template/settings_component_template
{
  "template":{
    "settings":{
      "number_of_shards":5,
      "number_of_replicas":2
    }
  }
}<p>Wie der obige Code zeigt, verwenden wir den Endpunkt _component_template, um eine Komponentenvorlage zu erstellen. Der Anfragetext enthält die Vorlageninformationen in einem Vorlagenobjekt. Die settings_component_template kann nun auch an anderer Stelle in den Indexvorlagen verwendet werden. Ein wesentlicher Unterschied besteht darin, dass diese Vorlage kein Indexmuster definiert; es handelt sich lediglich um einen Codeblock, der einige Eigenschaften für uns konfiguriert.</p><h3>Mapping-Vorlage</h3><p>Erstellen wir auf die gleiche Weise eine weitere Vorlage. Dieses Mal extrahieren wir das Mapping-Schema, das wir zuvor in den eigenständigen Indexvorlagen definiert hatten. Der folgende Code zeigt das Skript:</p>PUT _component_template/mappings_component_template
{
  "template": {
    "mappings": {
      "properties": {
        "order_date": {
          "type": "date",
          "format":"dd-MM-yyyy"
        }
      }
    }
  }
}<h3>Aliasvorlage</h3><p>Im gleichen Sinne können wir auch eine Komponentenvorlage mit den Aliasen haben – zwei Aliase (all_orders und sales_orders):</p>PUT _component_template/aliases_component_template
{
  "template": {
    "aliases": {
      "all_orders": {},
      "sales_orders":{}
    }
  }
}<h3>Vorlage für einen zusammensetzbaren Index</h3><p>Nachdem wir nun diese drei Komponentenvorlagen haben, besteht der nächste Schritt darin, sie einzusetzen. Wir können dies erreichen, indem wir eine Indexvorlage, beispielsweise für christmas_orders, diese verwenden lassen:</p>PUT _index_template/composed_orders_template
{
  "index_patterns": [
    "*orders"
  ],
  "priority": 500,
  "composed_of": [
    "settings_component_template",
    "mappings_component_template",
    "aliases_component_template"
  ]
}<p>Das `composed_of`-Tag ist eine Sammlung aller Komponentenvorlagen, aus denen diese Vorlage besteht. In diesem Fall wählen wir die Komponentenvorlagen für Einstellungen, Zuordnungen und Aliase aus. Wir erhöhen außerdem die Priorität, sodass diese Vorlage alle anderen übertrifft. Sobald die Vorlage fertig ist, erben alle Indizes, die dem Muster *orders entsprechen, die Konfiguration von diesen drei Komponentenvorlagen.</p><p>Wenn wir nun eine neue Vorlage, beispielsweise für Kunden, mit nur einer der bestehenden Vorlagen (settings_component_template) und einer neu erstellten Aliasvorlage (aliases_component_template – siehe unten) erstellen möchten, können wir dies wie folgt tun:</p>PUT _component_template/aliases_component_template2
{
  "template": {
    "aliases": {
      "all_customers": {}
    }
  }
}<p>Die Indexvorlage sieht folgendermaßen aus:</p>PUT _index_template/composed_customers_template
{
  "index_patterns": [
    "*customers*"
  ],
  "priority": 200,
  "composed_of": [
    "settings_component_template",
    "aliases_component_template2"
  ]
}<p>Ist Ihnen aufgefallen, dass die settings_component_template in zwei verschiedenen Templates (wieder)verwendet wurde? Das ist die Stärke von Komponentenvorlagen.</p><h2>Indexvorlagenpriorität</h2><p>Es besteht die Möglichkeit, dass Entwickler mehrere Indexvorlagen erstellen, ohne den vorhandenen Bestand zu berücksichtigen. Es ist wichtig, jeder dieser Vorlagen eine Priorität zuzuweisen, damit diejenige mit der höheren Priorität verwendet wird. Beispielsweise überschreibt my_orders_template_1 im folgenden Codeausschnitt my_orders_template_2:</p>PUT _index_template/my_orders_template_1
{
  "index_patterns": ["*orders"],
  "priority": 1000,
  "template": { ... }
}
PUT _index_template/my_orders_template2
{
  "index_patterns": ["*orders"],
  "priority": 300,
  "template": { ... }
}<p>Wenn mehrere Vorlagen zu den zu erstellenden Indizes passen, wendet Elasticsearch alle Konfigurationen aus allen passenden Vorlagen an, überschreibt aber alle Konfigurationen mit höherer Priorität.</p><h2>Priorität der Vorlagen</h2><p>Abschließend stellt sich vielleicht die Frage nach der Priorität der Vorlagen – überschreibt die in der Komponentenvorlage definierte Konfiguration diejenige, die in der Hauptindexvorlage selbst definiert ist? Oder umgekehrt? Nun ja, es gibt einige Regeln:</p><ul><li><p>Ein Index, der mit expliziten Konfigurationen erstellt wurde, hat Vorrang vor allem anderen – das bedeutet, wenn Sie einen Index mit expliziten Konfigurationen erstellen, können Sie nicht davon ausgehen, dass diese von den Vorlagen überschrieben werden.</p></li><li><p>Legacy-Vorlagen (Vorlagen, die vor Version 7.8 erstellt wurden) haben eine niedrigere Priorität als die zusammensetzbaren Vorlagen.</p></li></ul><h2>Zusammenfassung</h2><ul><li><p>Ein Index enthält Mappings, Einstellungen und Aliase: Die Mappings definieren das Feldschema, die Einstellungen legen die Indexparameter wie die Anzahl der Shards und Replikate fest, und die Aliase geben dem Index alternative Namen.</p></li><li><p>Mithilfe von Vorlagen können wir Indizes mit vordefinierten Konfigurationen erstellen. Wenn ein Index mit einem Namen benannt wird, der dem in einer bestimmten Vorlage definierten Indexmuster entspricht, wird dieser Index automatisch gemäß der Vorlage konfiguriert.</p></li><li><p>Elasticsearch führte in Version 7.8 zusammensetzbare Indexvorlagen ein. Zusammensetzbare Indexvorlagen ermöglichen Modularität und Versionierung von Vorlagen.</p></li><li><p>Die zusammensetzbaren Vorlagen bestehen aus keiner oder mehreren Komponentenvorlagen.</p></li><li><p>Eine Indexvorlage kann auch über eine eigene Konfiguration verfügen.</p></li><li><p>Eine Komponentenvorlage ist eine wiederverwendbare Vorlage mit vordefinierter Konfiguration, genau wie eine zusammensetzbare Indexvorlage.</p></li><li><p>Allerdings wird von Komponentenvorlagen erwartet, dass sie Teil einer Indexvorlage sind; sie sind nutzlos, wenn sie nicht in eine Indexvorlage „zusammengesetzt“ werden.</p></li><li><p>Komponentenvorlagen haben kein definiertes Indexmuster – was ein weiterer Grund dafür ist, dass sie „erwartet“ werden, Teil einer Indexvorlage zu sein.</p></li><li><p>Jede der Vorlagen hat eine Priorität – eine positive Zahl. Je höher die Zahl, desto höher ist die Priorität für die Anwendung dieser Vorlage.</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/index-composable-templates</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/index-composable-templates</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt98737a72caa74fe4/6a17f5b84b055d278d43236a/510750708df50bf79463586a1bbf35bf94acfa30-1200x628.png" length="0" type="image/png"/>
    <pubDate>Fri, 02 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Wie man Daten über Airbyte in Elasticsearch einliest]]></title>
    <description><![CDATA[Verwendung von Airbyte zum Einlesen von Daten in Elasticsearch. Wir werden die Voraussetzungen, die Airbyte-Konfiguration und die schrittweise Integration behandeln.]]></description>
    <content:encoded><![CDATA[<p>Airbyte ist ein Datenintegrationstool, mit dem Sie Informationen aus verschiedenen Quellen automatisiert und skalierbar an unterschiedliche Ziele übertragen können. Es ermöglicht Ihnen, Daten aus APIs, Datenbanken und anderen Systemen zu extrahieren und in Plattformen wie Elasticsearch zu laden, die eine erweiterte Suche und effiziente Analyse bieten.</p><p>In diesem Artikel erklären wir, wie Sie Airbyte für die Datenaufnahme in Elasticsearch konfigurieren. Dabei gehen wir auf wichtige Konzepte, Voraussetzungen und die schrittweise Integration ein.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt99eabff95c587c00/6a17e300e8fbce2d303a18a9/ea7af907dfd4c0b7e8673164467ee236623282d2-1360x802.png" alt="Konfigurieren Sie Airbyte so, dass Daten in Elasticsearch aufgenommen werden." /><h2>Grundkonzepte von Airbyte</h2><p>Airbyte basiert auf mehreren grundlegenden Nutzungskonzepten. Im Folgenden heben wir die wichtigsten hervor:</p><ul><li><p>Quellen: Definiert den Ursprung der zu extrahierenden Daten.</p></li><li><p>Ziele: Definiert, wohin die Daten gesendet und gespeichert werden.</p></li><li><p>Verbindungen: Konfiguriert die Beziehung zwischen Quelle und Ziel, einschließlich der Synchronisierungsfrequenz.</p></li></ul><h2>Airbyte-Integration mit Elasticsearch</h2><p>In dieser Demonstration führen wir eine Integration durch, bei der Daten, die in einem S3-Bucket gespeichert sind, in einen Elasticsearch-Index migriert werden. Wir zeigen Ihnen, wie Sie die Quelle (S3) und das Ziel (Elasticsearch) in Airbyte konfigurieren.</p><h3>Voraussetzungen</h3><p>Um dieser Demonstration folgen zu können, müssen folgende Voraussetzungen erfüllt sein:</p><ol><li><p>Erstellen Sie einen Bucket in AWS, in dem die JSON-Dateien mit den Daten gespeichert werden.</p></li><li><p><a href="https://docs.airbyte.com/using-airbyte/getting-started/oss-quickstart">Installieren Sie Airbyte lokal</a> mit Docker.</p></li><li><p>Erstellen Sie einen Elasticsearch-Cluster in Elastic Cloud, um die aufgenommenen Daten zu speichern.</p></li></ol><p>Im Folgenden werden wir jeden dieser Schritte detailliert beschreiben.</p><h4>Airbyte installieren</h4><p>Airbyte kann lokal mit Docker oder in der Cloud ausgeführt werden, wobei mit der Nutzung Kosten verbunden sind. Für diese Demonstration verwenden wir die lokale Version mit Docker.</p><p>Die Installation kann einige Minuten dauern. Nach Befolgung der Installationsanweisungen ist Airbyte unter folgender Adresse erreichbar: http://localhost:8000.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f9149be887b5500/6a17e302abe0f2b1c6dfe956/66147b5121413ad9baecb10c6886288e917f7c09-1600x1102.png" alt="Airbyte installieren" /><p></p><p>Nach dem Einloggen können wir mit der Konfiguration der Integration beginnen.</p><h4>Erstellen des Buckets</h4><p>In diesem Schritt benötigen Sie ein AWS-Konto, um einen S3-Bucket zu erstellen. Darüber hinaus ist es unerlässlich, die korrekten Berechtigungen festzulegen, indem eine Richtlinie und ein IAM-Benutzer erstellt werden, um den Zugriff auf den Bucket zu ermöglichen.</p><p>In den Bucket laden wir JSON-Dateien mit verschiedenen Log-Einträgen hoch, die später zu Elasticsearch migriert werden. Die Dateiprotokolle haben folgenden Inhalt:</p>{
   "timestamp": "2025-02-15T14:00:12Z",
   "level": "INFO",
   "service": "data_pipeline",
   "message": "Pipeline execution started",
   "details": {
       "pipeline_id": "abc123",
       "source": "MySQL",
       "destination": "Elasticsearch"
   }
}<p>Nachfolgend sind die in den Bucket geladenen Dateien aufgeführt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbf769c5e9bdb5dfe/6a17e3043e9e45a360ba13f7/f3e7f5889002e3a804121a880d97f1d93044e2f7-1600x680.png" alt="In Airbyte wurden Dateien in den Bucket geladen." /><h4>Elastic Cloud-Konfiguration</h4><p>Um die Demonstration zu vereinfachen, verwenden wir Elastic Cloud. Falls Sie noch kein Konto besitzen, können Sie hier ein kostenloses Testkonto erstellen: <a href="https://cloud.elastic.co/registration">Elastic Cloud-Registrierung</a>.</p><p>Nach der Konfiguration der Bereitstellung in Elastic Cloud benötigen Sie Folgendes:</p><ul><li><p>Die URL des Elasticsearch-Servers.</p></li><li><p>Ein Benutzer, der auf Elasticsearch zugreifen kann.</p></li></ul><p>Um die URL zu erhalten, gehen Sie zu Deployments &gt; My deployment, suchen Sie unter Anwendung nach Elasticsearch und klicken Sie auf 'Endpunkt kopieren'.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltddfaaf863168e2bb/6a17e305faa913e29793c7e4/2e38c0bfb2cea83d9ef90dba0e673559fe358199-1368x1056.png" alt="Elastic Cloud-Konfiguration" /><p>Um den Benutzer anzulegen, befolgen Sie die folgenden Schritte:</p><ol><li><p>Zugriff auf Kibana &gt; Stack-Management &gt; Benutzer.</p></li><li><p>Erstellen Sie einen neuen Benutzer mit der Rolle des Superusers.</p></li><li><p>Füllen Sie die Felder aus, um den Benutzer zu erstellen.</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca15b0d3084f4c67/6a17e3073e9e4507e2ba13fb/54d098805087a2d60772475cbb31784083a38c25-1600x1026.png" alt="Benutzer in Elastic Cloud erstellen" /><p>Nachdem wir nun alles eingerichtet haben, können wir mit der Konfiguration der Konnektoren in Airbyte beginnen.</p><h3>Quellanschluss konfigurieren</h3><p>In diesem Schritt erstellen wir den Quellkonnektor für S3. Dazu rufen wir die Airbyte-Benutzeroberfläche auf und wählen im Menü die Option „Quelle“ aus. Als Nächstes suchen wir nach dem S3-Anschluss. Im Folgenden beschreiben wir die erforderlichen Schritte zur Konfiguration des Konnektors:</p><ol><li><p>Öffnen Sie Airbyte und gehen Sie zum Menü „Quellen“.</p></li><li><p>Suchen und wählen Sie den S3-Anschluss aus.</p></li><li><p>Konfigurieren Sie die folgenden Parameter:</p><ol><li><p>Quellname: Geben Sie einen Namen für die Datenquelle an.</p></li><li><p>Zustellungsmethode: Datensätze replizieren (empfohlen für strukturierte Daten).</p></li><li><p>Datenformat: Wählen Sie das JSON-Format.</p></li><li><p>Stream-Name: Definieren Sie den Namen des Index in Elasticsearch.</p></li><li><p>Bucket-Name: Geben Sie den Namen des Buckets in AWS ein.</p></li><li><p>AWS-Zugriffsschlüssel und AWS-Geheimschlüssel: Geben Sie die Zugangsdaten ein.</p></li></ol></li></ol><p>Klicken Sie auf „Quelle einrichten“ und warten Sie auf die Validierung.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdca1fb8d8f5d034f/6a17e30963baff75bc741bb2/f83566ab5ebad07ad9fd61dc20353ca5a95c8c92-1600x1099.png" alt="Warten Sie auf die Validierung der Datenaufnahme von Airbyte und Elasticsearch." /><h3>Konfigurationszielkonnektor</h3><p>In diesem Schritt konfigurieren wir den Zielkonnektor, und zwar Elasticsearch. Dazu rufen wir das Menü auf und wählen die Option „Ziel“. Anschließend suchen wir nach Elasticsearch und klicken auf das angezeigte Ergebnis. Nun fahren wir mit der Konfiguration dieser Verbindung fort:</p><ol><li><p>Öffnen Sie Airbyte und gehen Sie zum Menü „Ziele“.</p></li><li><p>Suchen und wählen Sie den Elasticsearch-Connector aus.</p></li><li><p>Konfigurieren Sie die folgenden Parameter:</p><ol><li><p>Authentifizierungsmethode: Benutzername/Passwort auswählen.</p></li><li><p>Benutzername und Passwort: Verwenden Sie die in Kibana erstellten Zugangsdaten.</p></li><li><p>Server-Endpunkt: Fügen Sie die aus Elastic Cloud kopierte URL ein.</p></li></ol></li></ol><p>Klicken Sie auf <strong>„Ziel einrichten“</strong> und warten Sie auf die Bestätigung.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72056179d048e027/6a17e30b033c8d5d9d6bb115/f9246b54cc77e0589c0bf658ffc274fd28f766d5-1600x941.png" alt="Erstellen Sie ein Ziel in Elastic Cloud für die Airbyte-Datenerfassung." /><h3>Erstellen der Quell- und Zielverbindung</h3><p>Sobald Quelle und Ziel erstellt sind, wird die Verbindung zwischen ihnen hergestellt, womit die Integration abgeschlossen ist. </p><p>Nachfolgend finden Sie die Anweisungen zum Herstellen der Verbindung:</p><p>1. Im Menü gehen Sie zu Verbindungen und klicken Sie auf Erste Verbindung erstellen.</p><p>2. Im nächsten Bildschirm können Sie eine bestehende Quelle auswählen oder eine neue erstellen. Da wir bereits eine Quelle erstellt haben, wählen wir Quelle S3 aus.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc7f1e01215a7a328/6a17e30c63baff53d7741bb6/14937ccb2686bbde7cb99ffe7e13f7f4e35d7a31-1600x393.png" alt="Wählen Sie in Airbyte eine vorhandene Quelle aus oder erstellen Sie eine neue." /><p>3. Im nächsten Schritt muss das Reiseziel ausgewählt werden. Da wir den Elasticsearch-Connector bereits erstellt haben, wird dieser zur Vervollständigung der Konfiguration ausgewählt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltece5c720f28eee00/6a17e30d505ac3dc68ad8aa3/d10962bc175f9ce0b2745ea913d739d3c40ba3b6-1600x431.png" alt="Wählen Sie das Ziel in Airbyte aus." /><p>Im nächsten Schritt muss der Synchronisierungsmodus und das zu verwendende Schema definiert werden. Da nur das Protokollschema erstellt wurde, ist dies die einzige auswählbare Option.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7cbcccad9cfd5a8d/6a17e30f414c64d32d9450e9/d5d3a2e20038d17ef701822fe7ccc38d6e175c50-1600x805.png" alt="Den Synchronisierungsmodus in Airbyte definieren" /><p>4. Wir fahren nun mit dem Schritt „Verbindung konfigurieren“ fort. Hier können wir den Namen der Verbindung und die Häufigkeit der Integrationsausführung festlegen. Die Frequenz kann auf drei Arten konfiguriert werden:</p><ul><li><p><strong>Cron</strong>: Führt die Synchronisierungen gemäß dem benutzerdefinierten Cron-Ausdruck aus (z. B. 0 0 15 * * ?, Jeden Tag um 15:00 Uhr);</p></li><li><p><strong>Geplant</strong>: Führt die Synchronisierungen im angegebenen Zeitintervall aus (z. B. alle 24 Stunden, alle 2 Stunden);</p></li><li><p><strong>Manuell</strong>: Synchronisierungen manuell ausführen.</p></li></ul><p>Für diese Demonstration wählen wir die Option „Manuell“.</p><p>Durch Klicken auf <strong>„Verbindung einrichten“</strong> wird abschließend die Verbindung zwischen Quelle und Ziel hergestellt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4f5fc0e51035b733/6a17e311af47b67ac8cddeff/1a0470f6dff341cb90e6ecfd8ae87a7d2243cbf4-1600x626.png" alt="Klicken auf „Verbindung einrichten“ in Airbyte" /><h3>Synchronisierung von Daten von S3 zu Elasticsearch</h3><p>Wenn Sie zum Bildschirm „Verbindungen“ zurückkehren, können Sie die erstellte Verbindung sehen. Um den Vorgang auszuführen, klicken Sie einfach auf Synchronisieren. Ab diesem Zeitpunkt beginnt die Migration der Daten von S3 zu Elasticsearch.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9b0ad7a7446f9d58/6a17e3121d1b83b4c593e3c3/c1ce54b129eafb2533b638e4df2b96f3a266ad62-1600x347.png" alt="Synchronisierung von Daten von S3 zu Elasticsearch auf Airbyte" /><p>Wenn alles reibungslos verläuft, erhalten Sie den Synchronisierungsstatus.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt857cdad5bd7fe03f/6a17e313be608646e00046b9/6fe9d5826787066bd8bf0f5e17905df9f8d698e6-1600x361.png" alt="Synchronisierungsstatus von S3 zu Elasticsearch in Airbyte" /><h3>Datenvisualisierung in Kibana</h3><p>Nun werden wir zu Kibana wechseln, um die Daten zu analysieren und zu überprüfen, ob sie korrekt indiziert wurden. Im Abschnitt „Kibana Discovery“ erstellen wir eine Datenansicht namens „logs“. Damit können wir die Daten untersuchen, die nur im Protokollindex vorhanden sind, der nach der Synchronisierung erstellt wurde.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1bc137f7c04e50ee/6a17e3151480094f2eb486cf/6b6909647ac3187d0fee477cfd732741314f82cf-1600x566.png" alt="Datenvisualisierung in Kibana: Airbyte und Elastic" /><p>Nun können wir die indizierten Daten visualisieren und Analysen daran durchführen. Auf diese Weise haben wir den gesamten Migrationsablauf mit Airbyte validiert, wo wir die im Bucket vorhandenen Daten geladen und in Elasticsearch indiziert haben.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd8c0a36a83ee4bb1/6a17e317b1e1135ea679f20e/ca8e9b3d7f7112291af58acf514f4573b44037e8-1600x806.png" alt="Airbyte und Elastic: Visualisieren Sie die indizierten Daten und führen Sie Analysen in Kibana durch." /><h2>Fazit: Integration von Airbyte und Elasticsearch</h2><p>Airbyte erwies sich als effizientes Werkzeug zur Datenintegration, mit dem wir mehrere Quellen und Ziele automatisiert verbinden konnten. In diesem Tutorial haben wir gezeigt, wie man Daten aus einem S3-Bucket in einen Elasticsearch-Index einliest, und dabei die wichtigsten Schritte des Prozesses hervorgehoben.</p><p>Dieser Ansatz erleichtert die Aufnahme großer Datenmengen und ermöglicht Analysen innerhalb von Elasticsearch, wie z. B. komplexe Suchvorgänge, Aggregationen und Datenvisualisierungen.</p><h2>Referenzen</h2><p><strong>Quickstart Airbyte:</strong></p><p><a href="https://docs.airbyte.com/using-airbyte/getting-started/oss-quickstart#part-1-install-abctl">https://docs.airbyte.com/using-airbyte/getting-started/oss-quickstart#part-1-install-abctl</a></p><p><strong>Kernkonzepte:</strong></p><p><a href="https://docs.airbyte.com/using-airbyte/core-concepts/">https://docs.airbyte.com/using-airbyte/core-concepts/</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/airbyte-elasticsearch-ingest-data</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/airbyte-elasticsearch-ingest-data</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5defe5e12935b233/6a17e318505ac3ed7fad8aa7/dce2bad9949006163af95ed05b5a1eacf5393dc7-1200x628.png" length="0" type="image/png"/>
    <pubDate>Fri, 14 Mar 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Wie man Daten über LlamaIndex in Elasticsearch einliest]]></title>
    <description><![CDATA[Eine Schritt-für-Schritt-Anleitung zur Datenaufnahme und -suche mit RAG und LlamaIndex.]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel implementieren wir eine Suchmaschine für FAQs, wobei wir LlamaIndex zur Datenindizierung verwenden. Elasticsearch dient als unsere Vektordatenbank und ermöglicht die Vektorsuche, während RAG (Retrieval-Augmented Generation) den Kontext anreichert und so genauere Antworten liefert.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte5895fbc057ffc1b/6a17f4cf3e9e45288bba15ef/7ac65a686bdd76c145e903f5c3110c62875a525f-972x501.png" alt="LlamaIndex &amp; Elasticsearch: Dokumente einlesen und FAQ-Suche erstellen" /><h2>Was ist LlamaIndex?</h2><p>LlamaIndex ist ein Framework, das die Erstellung von Agenten und Workflows erleichtert, die auf großen Sprachmodellen (LLMs) basieren und mit spezifischen oder privaten Daten interagieren. Es ermöglicht die Integration von Daten aus verschiedenen Quellen (APIs, PDFs, Datenbanken) in LLMs und ermöglicht so Aufgaben wie Recherche, Informationsgewinnung und die Generierung kontextbezogener Antworten.</p><p><strong>Schlüsselkonzepte:</strong></p><ul><li><p>Agenten: Intelligente Assistenten, die LLMs verwenden, um Aufgaben auszuführen, die von einfachen Antworten bis hin zu komplexen Aktionen reichen.</p></li><li><p>Workflows: Mehrstufige Prozesse, die Agenten, Datenkonnektoren und Tools für fortgeschrittene Aufgaben kombinieren.</p></li><li><p>Kontexterweiterung: Eine Technik, die das LLM mit externen Daten anreichert und so seine Trainingsbeschränkungen überwindet.</p></li></ul><p><strong>LlamaIndex-</strong> <strong>Integration mit Elasticsearch:</strong></p><p>Elasticsearch kann auf verschiedene Weise mit LlamaIndex verwendet werden:</p><ul><li><p>Datenquelle: Verwenden Sie den Elasticsearch Reader, um Dokumente zu extrahieren.</p></li><li><p>Einbettungsmodell: Daten werden für semantische Suchen in Vektoren kodiert.</p></li><li><p>Vektorspeicherung: Verwenden Sie Elasticsearch als Repository für die Suche nach vektorisierten Dokumenten.</p></li><li><p>Erweiterter Speicher: Konfigurieren Sie Strukturen wie Dokumentzusammenfassungen oder Wissensgraphen.</p></li></ul><h2>Verwendung von LlamaIndex und Elasticsearch zum Erstellen einer FAQ-Suche </h2><h3>Datenaufbereitung</h3><p>Wir werden die <a href="https://www.elastic.co/guide/en/cloud/current/ec-faq-getting-started.html">FAQ zum Elasticsearch-Dienst</a> als Beispiel verwenden. Jede Frage wurde von der Webseite extrahiert und in einer separaten Textdatei gespeichert. Sie können jeden beliebigen Ansatz zur Organisation der Daten verwenden; in diesem Beispiel haben wir uns dafür entschieden, die Dateien lokal zu speichern.</p><p>Beispieldatei:</p>File Name: what-is-elasticsearch-service.txt
Content: Elasticsearch Service is hosted and managed Elasticsearch and Kibana brought to you by the creators of Elasticsearch. Elasticsearch Service is part of Elastic Cloud and ships with features that you can only get from the company behind Elasticsearch, Kibana, Beats, and Logstash. Elasticsearch is a full text search engine that suits a range of uses, from search on websites to big data analytics and more.<p>Nach dem Speichern aller Fragen sieht das Verzeichnis folgendermaßen aus:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt43467eb9c5579103/6a17f4d02f4a5cc60bfa8a62/1f367d57f2e650334671a2c03156ef4412c0c615-962x704.png" alt="" /><h3>Installation der Abhängigkeiten</h3><p>Die Datenerfassung und -suche werden wir mit Hilfe der Programmiersprache Python implementieren; ich habe Version 3.9 verwendet. Als Voraussetzung müssen die folgenden Abhängigkeiten installiert werden:</p>llama-index-vector-stores-elasticsearch
llama-index
openai<p>Elasticsearch und Kibana werden mit Docker erstellt und über docker-compose.yml so konfiguriert, dass sie in Version 8.16.2 ausgeführt werden. Dadurch wird die Schaffung der lokalen Umgebung erleichtert.</p>version: '3.8'
services:

 elasticsearch:
   image: docker.elastic.co/elasticsearch/elasticsearch:8.16.2
   container_name: elasticsearch-8.16.2
   environment:
     - node.name=elasticsearch
     - xpack.security.enabled=false
     - discovery.type=single-node
     - "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
   ports:
     - 9200:9200
   networks:
     - shared_network

 kibana:
   image: docker.elastic.co/kibana/kibana:8.16.2
   container_name: kibana-8.16.2
   restart: always
   environment:
     - ELASTICSEARCH_URL=http://elasticsearch:9200
   ports:
     - 5601:5601
   depends_on:
     - elasticsearch
   networks:
     - shared_network

networks:
 shared_network:<h3>Dokumentenaufnahme mit LlamaIndex</h3><p>Die Dokumente werden mithilfe von LlamaIndex in Elasticsearch indexiert. Zuerst laden wir die Dateien mit <strong>SimpleDirectoryReader</strong>, das das Laden von Dateien aus einem lokalen Verzeichnis ermöglicht. Nach dem Laden der Dokumente werden wir sie mithilfe des <strong>VectorStoreIndex</strong> indizieren.</p>documents = SimpleDirectoryReader("./faq").load_data()

storage_context = StorageContext.from_defaults(vector_store=es)
index = VectorStoreIndex(documents, storage_context=storage_context, embed_model=embed_model)<p>Die Vektorspeicher in LlamaIndex sind für das Speichern und Verwalten von Dokumenteneinbettungen zuständig. LlamaIndex unterstützt verschiedene Arten von Vektorspeichern, und in diesem Fall verwenden wir Elasticsearch. Im StorageContext konfigurieren wir die Elasticsearch-Instanz. Da der Kontext lokal ist, waren keine zusätzlichen Parameter erforderlich. Für Konfigurationen in anderen Umgebungen konsultieren Sie bitte die Dokumentation, um die erforderlichen Parameter zu überprüfen: <a href="https://docs.llamaindex.ai/en/stable/examples/vector_stores/ElasticsearchIndexDemo/#configuring-elasticsearchstore">ElasticsearchStore-Konfiguration</a>.</p><p>Standardmäßig verwendet LlamaIndex das OpenAI <strong>text-embedding-ada-002-</strong> Modell zur Generierung von Einbettungen. In diesem Beispiel verwenden wir jedoch das Modell <strong>text-embedding-3-small</strong> . Wichtig zu beachten ist, dass für die Nutzung des Modells ein OpenAI-API-Schlüssel erforderlich ist.</p><p>Nachfolgend finden Sie den vollständigen Code für die Dokumentenaufnahme.</p>import openai
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.vector_stores.elasticsearch import ElasticsearchStore

openai.api_key = os.environ["OPENAI_API_KEY"]

es = ElasticsearchStore(
   index_name="faq",
   es_url="http://localhost:9200"
)

def format_title(filename):
   filename_without_ext = filename.replace('.txt', '')
   text_with_spaces = filename_without_ext.replace('-', ' ')
   formatted_text = text_with_spaces.title()

   return formatted_text


embed_model = OpenAIEmbedding(model="text-embedding-3-small")

documents = SimpleDirectoryReader("./faq").load_data()

for doc in documents:
   doc.metadata['title'] = format_title(doc.metadata['file_name'])

storage_context = StorageContext.from_defaults(vector_store=es)
index = VectorStoreIndex(documents, storage_context=storage_context, embed_model=embed_model)<p>Nach der Ausführung werden die Dokumente wie unten dargestellt im <strong>FAQ-</strong> Index indexiert:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt391ae1bfc1daefbf/6a17f4d22f4a5c9887fa8a66/d59b85ed1f57bf80e84d6cb0d6d722a2d12ae4c0-1600x745.png" alt="" /><h3>Suche mit RAG</h3><p>Um Suchvorgänge durchzuführen, konfigurieren wir den <strong>ElasticsearchStore-</strong> Client, indem wir die Felder <strong>index_name</strong> und <strong>es_url</strong> mit der Elasticsearch-URL belegen. In <strong>retrieval_strategy</strong> haben wir die <strong>AsyncDenseVectorStrategy</strong> für Vektorsuchen definiert. Es stehen auch andere Strategien zur Verfügung, wie zum Beispiel <strong>AsyncBM25Strategy</strong> (Stichwortsuche) und <strong>AsyncSparseVectorStrategy</strong> (dünnbesetzte Vektoren). Weitere Einzelheiten finden Sie in der <a href="https://docs.llamaindex.ai/en/stable/api_reference/storage/vector_store/elasticsearch/">offiziellen Dokumentation</a>.</p>es = ElasticsearchStore(
   index_name="faq",
   es_url="http://localhost:9200",
   retrieval_strategy=AsyncDenseVectorStrategy(
   )
)<p>Als nächstes wird ein <strong>VectorStoreIndex-</strong> Objekt erstellt, in dem wir den <strong>vector_store</strong> mithilfe des ElasticsearchStore-Objekts konfigurieren. Mit der Methode <strong>as_retriever</strong> führen wir die Suche nach den relevantesten Dokumenten für eine Anfrage durch und legen die Anzahl der zurückgegebenen Ergebnisse über den Parameter <strong>similarity_top_k</strong> auf 5 fest.</p>   index = VectorStoreIndex.from_vector_store(vector_store=es)
   retriever = index.as_retriever(similarity_top_k=5)
   results = retriever.retrieve(query)<p>Der nächste Schritt ist RAG. Die Ergebnisse der Vektorsuche werden in eine formatierte Eingabeaufforderung für das LLM integriert, wodurch eine kontextbezogene Antwort auf Basis der abgerufenen Informationen ermöglicht wird.</p><p>In der PromptTemplate definieren wir das Prompt-Format, das Folgendes umfasst:</p><ul><li><p>Kontext ({context_str}): Vom Abrufer abgerufene Dokumente.</p></li><li><p>Anfrage ({query_str}): die Frage des Benutzers.</p></li><li><p>Anleitung: Richtlinien für das Modell, um kontextbezogen zu reagieren, ohne auf externes Wissen zurückzugreifen.</p></li></ul>qa_prompt = PromptTemplate(
   "You are a helpful and knowledgeable assistant."
   "Your task is to answer the user's query based solely on the context provided below."
   "Do not use any prior knowledge or external information.\n"
   "---------------------\n"
   "Context:\n"
   "{context_str}\n"
   "---------------------\n"
   "Query: {query_str}\n"
   "Instructions:\n"
   "1. Carefully read and understand the context provided.\n"
   "2. If the context contains enough information to answer the query, provide a clear and concise answer.\n"
   "3. Do not make up or guess any information.\n"
   "Answer: "
)<p>Schließlich verarbeitet das LLM die Eingabeaufforderung und gibt eine präzise und kontextbezogene Antwort zurück.</p>llm = OpenAI(model="gpt-4o")
context_str = "\n\n".join([n.node.get_content() for n in results])
response = llm.complete(
   qa_prompt.format(context_str=context_str, query_str=query)
)

print("Answer:")
print(response)<p>Der vollständige Code ist unten aufgeführt:</p>es = ElasticsearchStore(
   index_name="faq",
   es_url="http://localhost:9200",
   retrieval_strategy=AsyncDenseVectorStrategy(
   )
)


def print_results(results):
   for rank, result in enumerate(results, start=1):
       title = result.metadata.get("title")
       score = result.get_score()
       text = result.get_text()
       print(f"{rank}. title={title} \nscore={score} \ncontent={text}")


def search(query: str):
   index = VectorStoreIndex.from_vector_store(vector_store=es)

   retriever = index.as_retriever(similarity_top_k=10)
   results = retriever.retrieve(QueryBundle(query_str=query))
   print_results(results)

   qa_prompt = PromptTemplate(
       "You are a helpful and knowledgeable assistant."
       "Your task is to answer the user's query based solely on the context provided below."
       "Do not use any prior knowledge or external information.\n"
       "---------------------\n"
       "Context:\n"
       "{context_str}\n"
       "---------------------\n"
       "Query: {query_str}\n"
       "Instructions:\n"
       "1. Carefully read and understand the context provided.\n"
       "2. If the context contains enough information to answer the query, provide a clear and concise answer.\n"
       "3. Do not make up or guess any information.\n"
       "Answer: "
   )

   llm = OpenAI(model="gpt-4o")
   context_str = "\n\n".join([n.node.get_content() for n in results])
   response = llm.complete(
       qa_prompt.format(context_str=context_str, query_str=query)
   )

   print("Answer:")
   print(response)


question = "Elastic services are free?"
print(f"Question: {question}")
search(question)<p>Nun können wir unsere Suche durchführen, zum Beispiel: „Sind Elastic-Dienste kostenlos?“, und erhalten eine kontextbezogene Antwort, die auf den FAQ-Daten selbst basiert.</p>Question: Elastic services are free?
Answer:
Elastic services are not entirely free. However, there is a 14-day free trial available for exploring Elastic solutions. After the trial, access to features and services depends on the subscription level.<p>Zur Erstellung dieser Antwort wurden folgende Dokumente verwendet:</p>1. title=Can I Try Elasticsearch Service For Free 
score=1.0 
content=Yes, sign up for a 14-day free trial. The trial starts the moment a cluster is created.
During the free trial period get access to a deployment to explore Elastic solutions for Enterprise Search, Observability, Security, or the latest version of the Elastic Stack.

2. title=Do You Offer Elastic S Commercial Products 
score=0.9941274512218439 
content=Yes, all Elasticsearch Service customers have access to basic authentication, role-based access control, and monitoring.
Elasticsearch Service Gold, Platinum and Enterprise customers get complete access to all the capabilities in X-Pack: Security, Alerting, Monitoring, Reporting, Graph Analysis &amp; Visualization. Contact us to learn more.

3. title=What Is Elasticsearch Service 
score=0.9896776845746571 
content=Elasticsearch Service is hosted and managed Elasticsearch and Kibana brought to you by the creators of Elasticsearch. Elasticsearch Service is part of Elastic Cloud and ships with features that you can only get from the company behind Elasticsearch, Kibana, Beats, and Logstash. Elasticsearch is a full text search engine that suits a range of uses, from search on websites to big data analytics and more.

4. title=Can I Run The Full Elastic Stack In Elasticsearch Service 
score=0.9880631561979476 
content=Many of the products that are part of the Elastic Stack are readily available in Elasticsearch Service, including Elasticsearch, Kibana, plugins, and features such as monitoring and security. Use other Elastic Stack products directly with Elasticsearch Service. For example, both Logstash and Beats can send their data to Elasticsearch Service. What is run is determined by the subscription level.

5. title=What Is The Difference Between Elasticsearch Service And The Amazon Elasticsearch Service 
score=0.9835054890793161 
content=Elasticsearch Service is the only hosted and managed Elasticsearch service built, managed, and supported by the company behind Elasticsearch, Kibana, Beats, and Logstash. With Elasticsearch Service, you always get the latest versions of the software. Our service is built on best practices and years of experience hosting and managing thousands of Elasticsearch clusters in the Cloud and on premise. For more information, check the following Amazon and Elastic Elasticsearch Service comparison page.
Please note that there is no formal partnership between Elastic and Amazon Web Services (AWS), and Elastic does not provide any support on the AWS Elasticsearch Service.<h2>Fazit</h2><p>Anhand von LlamaIndex haben wir demonstriert, wie man ein effizientes FAQ-Suchsystem mit Unterstützung für Elasticsearch als Vektordatenbank erstellt. Die Dokumente werden mithilfe von Einbettungen erfasst und indexiert, wodurch Vektorsuchen ermöglicht werden. Mithilfe einer PromptTemplate werden die Suchergebnisse in den Kontext eingebunden und an das LLM gesendet, das auf Basis der abgerufenen Dokumente präzise und kontextbezogene Antworten generiert.</p><p>Dieser Workflow integriert die Informationsabfrage mit der kontextbezogenen Antwortgenerierung, um genaue und relevante Ergebnisse zu liefern.</p><h2>Referenzen</h2><p><a href="https://www.elastic.co/guide/en/cloud/current/ec-faq-getting-started.html">https://www.elastic.co/guide/en/cloud/current/ec-faq-getting-started.html</a></p><p><a href="https://docs.llamaindex.ai/en/stable/api_reference/readers/elasticsearch/">https://docs.llamaindex.ai/en/stable/api_reference/readers/elasticsearch/</a></p><p><a href="https://docs.llamaindex.ai/en/stable/module_guides/indexing/vector_store_index/">https://docs.llamaindex.ai/en/stable/module_guides/indexing/vector_store_index/</a></p><p><a href="https://docs.llamaindex.ai/en/stable/examples/query_engine/custom_query_engine/">https://docs.llamaindex.ai/en/stable/examples/query_engine/custom_query_engine/</a></p><p><a href="https://www.elastic.co/search-labs/integrations/llama-index">https://www.elastic.co/search-labs/integrations/llama-index</a></p><p></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-llamaindex-ingest-data</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-llamaindex-ingest-data</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf9f88afa92e90390/6a17f4d33e03d7987d4f2dd0/b8b760bfd8694df43fd74ba90ae5fc1edbe4ce76-1150x628.png" length="0" type="image/png"/>
    <pubDate>Fri, 28 Feb 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Wie man Daten über Apache Airflow in Elasticsearch ingestiert]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie Daten mithilfe von Apache Airflow in Elasticsearch einlesen.]]></description>
    <content:encoded><![CDATA[<h2>Was ist Apache Airflow?</h2><p>Apache Airflow ist eine Plattform, die zum Erstellen, Planen und Überwachen von Arbeitsabläufen entwickelt wurde. Es dient zur Orchestrierung von ETL-Prozessen, Datenpipelines und anderen komplexen Arbeitsabläufen und bietet Flexibilität und Skalierbarkeit. Die visuelle Benutzeroberfläche und die Echtzeit-Überwachungsfunktionen machen das Pipeline-Management zugänglicher und effizienter und ermöglichen es Ihnen, den Fortschritt und die Ergebnisse Ihrer Ausführungen zu verfolgen. Nachfolgend sind die vier Hauptpfeiler aufgeführt:</p><ul><li><p><strong>Dynamisch: </strong>Pipelines werden in Python definiert, was eine dynamische und flexible Workflow-Generierung ermöglicht.</p></li><li><p><strong>Erweiterbar:</strong> Airflow lässt sich in eine Vielzahl von Umgebungen integrieren, benutzerdefinierte Operatoren können erstellt und spezifischer Code nach Bedarf ausgeführt werden.</p></li><li><p><strong>Elegant:</strong> Pipelines werden sauber und explizit geschrieben.</p></li><li><p><strong>Skalierbar:</strong> Dank seiner modularen Architektur nutzt es eine Message Queue, um eine beliebige Anzahl von Workern zu orchestrieren.</p></li></ul><p>In der Praxis kann Airflow in Szenarien wie den folgenden eingesetzt werden:</p><ul><li><p><strong>Datenimport: </strong>Orchestrieren Sie die tägliche Datenaufnahme in eine Datenbank wie Elasticsearch.</p></li><li><p><strong>Protokollüberwachung:</strong> Verwaltung der Erfassung und Verarbeitung von Protokolldateien, die anschließend in Elasticsearch analysiert werden, um Fehler oder Anomalien zu identifizieren.</p></li><li><p><strong>Integration mehrerer Datenquellen:</strong> Informationen aus verschiedenen Systemen (APIs, Datenbanken, Dateien) werden in einer einzigen Ebene in Elasticsearch kombiniert, was die Suche und Berichterstellung vereinfacht.</p></li></ul><h2>Verständnis von gerichteten azyklischen Graphen (DAGs) in der Luftströmung</h2><p>In Airflow werden Workflows durch DAGs (gerichtete azyklische Graphen) dargestellt. Ein DAG ist eine Struktur, die die Reihenfolge definiert, in der Aufgaben ausgeführt werden. Die Hauptmerkmale von DAGs sind:</p><ul><li><p><strong>Zusammensetzung aus unabhängigen Aufgaben:</strong> Jede Aufgabe stellt eine Arbeitseinheit dar und ist so konzipiert, dass sie unabhängig ausgeführt werden kann.</p></li><li><p><strong>Sequenzierung: </strong>Die Reihenfolge, in der die Aufgaben ausgeführt werden, ist im DAG explizit definiert.</p></li><li><p><strong>Wiederverwendbarkeit:</strong> DAGs sind so konzipiert, dass sie wiederholt ausgeführt werden können, was die Prozessautomatisierung erleichtert.</p></li></ul><h2>Luftstromkomponenten</h2><p>Das Airflow-Ökosystem besteht aus mehreren Komponenten, die zusammenarbeiten, um Aufgaben zu orchestrieren:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt25a23489b8725b3e/6a17dfcfe8fbceba103a1846/bacd83aff625026d62f023e0434baa5782a2761a-1046x628.png" alt="Hauptkomponenten des Luftstroms" /><ul><li><p><strong>Scheduler:</strong> Verantwortlich für die Planung von DAGs und die Zuweisung von Aufgaben zur Ausführung an die Worker.</p></li><li><p><strong>Ausführender:</strong> Steuert die Ausführung von Aufgaben und delegiert diese an Mitarbeiter.</p></li><li><p><strong>Webserver:</strong> Bietet eine grafische Benutzeroberfläche zur Interaktion mit DAGs und Tasks.</p></li><li><p><strong>Dags-Ordner:</strong> Ordner, in dem wir in Python geschriebene DAGs speichern.</p></li><li><p><strong>Metadaten:</strong> Datenbank, die als Repository für das Tool dient und vom Scheduler und Executor zur Speicherung des Ausführungsstatus verwendet wird.</p></li></ul><h2>Apache Airflow und Elasticsearch</h2><p>Wir werden die Verwendung von Apache Airflow und Elasticsearch zur Orchestrierung von Aufgaben und zur Indizierung von Ergebnissen in Elasticsearch demonstrieren. Ziel dieser Demonstration ist es, eine Aufgabenpipeline zu erstellen, um Datensätze in einem Elasticsearch-Index zu aktualisieren. Dieser Index enthält eine Datenbank mit Filmen, in der Benutzer Bewertungen abgeben und andere Bewertungen vergeben können. Stellt man sich ein Szenario mit Hunderten von täglichen Bewertungen vor, ist es notwendig, die Bewertungsstatistik stets aktuell zu halten. Hierfür wird ein DAG entwickelt, der täglich ausgeführt wird und für das Abrufen der neuen konsolidierten Ratings sowie die Aktualisierung der Datensätze im Index zuständig ist.</p><p>Im DAG-Ablauf gibt es eine Aufgabe zum Abrufen der Bewertungen, gefolgt von einer Aufgabe zur Validierung der Ergebnisse. Falls die Daten nicht vorhanden sind, wird der DAG zu einer Fehleraufgabe weitergeleitet. Andernfalls werden die Daten in Elasticsearch indexiert. Ziel ist es, das Bewertungsfeld von Filmen in einem Index zu aktualisieren, indem die Bewertungen mithilfe einer Methode abgerufen werden, die den Mechanismus zur Berechnung der Punktzahlen beinhaltet.</p><h2>Verwendung von Apache Airflow und Elasticsearch mit Docker</h2><p>Um eine containerisierte Umgebung zu erstellen, verwenden wir Apache Airflow mit Docker. Folgen Sie den Anweisungen im Leitfaden <a href="https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html">„Airflow in Docker ausführen“,</a> um Airflow praktisch einzurichten.</p><p>Was Elasticsearch betrifft, werde ich einen Cluster auf Elastic Cloud verwenden, aber wenn Sie es vorziehen, können Sie Elasticsearch auch mit Docker konfigurieren. Es wurde bereits ein Index erstellt, der einen Filmkatalog mit den indexierten Filmdaten enthält. Das Feld „Bewertung“ dieser Filme wird aktualisiert.</p><h2>Erstellung des DAG</h2><p>Nach der Installation via Docker wird eine Ordnerstruktur erstellt, die unter anderem den Ordner „dags“ enthält. In diesem Ordner müssen wir unsere DAG-Dateien ablegen, damit Airflow sie erkennt.</p><p>Zuvor müssen wir sicherstellen, dass die notwendigen Abhängigkeiten installiert sind. Hier sind die Abhängigkeiten für dieses Projekt:</p>pip install apache-airflow apache-airflow-providers-elasticsearch<p>Wir werden die Datei <code>update_ratings_movies.py</code> erstellen und mit der Codierung der Aufgaben beginnen.</p><p>Nun importieren wir die benötigten Bibliotheken:</p>from airflow import DAG
from airflow.operators.python import PythonOperator, BranchPythonOperator
from airflow.providers.elasticsearch.hooks.elasticsearch import ElasticsearchPythonHook<p>Wir werden den <a href="https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/stable/hooks/elasticsearch_python_hook.html"><strong>ElasticsearchPythonHook</strong></a> verwenden, eine Komponente, die die Integration zwischen Airflow und einem Elasticsearch-Cluster vereinfacht, indem sie die Verbindung und die Verwendung externer APIs abstrahiert.</p><p>Als Nächstes definieren wir den DAG und geben seine Hauptargumente an:</p><ul><li><p><strong><code>dag_id</code></strong>: der Name des DAG.</p></li><li><p><strong><code>start_date</code></strong>: wann der DAG startet.</p></li><li><p><strong><code>schedule</code></strong>: definiert die Periodizität (in unserem Fall täglich).</p></li><li><p><strong><code>doc_md</code></strong>: Dokumentation, die importiert und in der Airflow-Oberfläche angezeigt wird.</p></li></ul><h2>Definition der Aufgaben</h2><p>Nun definieren wir die Aufgaben des DAG. Die erste Aufgabe besteht darin, die Daten zur Filmbewertung abzurufen. Wir werden den <strong>PythonOperator</strong> verwenden, wobei <code>task_id</code> auf <code>'get_movie_ratings'</code> gesetzt ist. Der Parameter <code>python_callable</code> ruft die Funktion auf, die für das Abrufen der Bewertungen zuständig ist.</p>get_ratings_operator = PythonOperator(
   task_id='get_movie_ratings',
   python_callable=get_movie_ratings_task
)<p>Als nächstes müssen wir überprüfen, ob die Ergebnisse gültig sind. Hierfür verwenden wir eine Bedingung mit einem <strong>BranchPythonOperator</strong>. Die <code>task_id</code> wird zu <code>'validate_result'</code>, und die <code>python_callable</code> ruft die Validierungsfunktion auf. Der Parameter <code>op_args</code> wird verwendet, um das Ergebnis der vorherigen Aufgabe, <code>'get_movie_ratings'</code>, an die Validierungsfunktion zu übergeben.</p>validate_result = BranchPythonOperator(
   task_id='validate_result',
   python_callable=validate_result,
   op_args=["{{ task_instance.xcom_pull(task_ids='get_movie_ratings') }}"]
)<p>Wenn die Validierung erfolgreich ist, werden wir die Daten aus der <code>'get_movie_ratings'</code> -Aufgabe nehmen und in Elasticsearch indizieren. Um dies zu erreichen, erstellen wir eine neue Aufgabe, <code>'index_movie_ratings'</code>, die den <strong>PythonOperator</strong> verwendet. Der Parameter <code>op_args</code> übergibt die Ergebnisse der Aufgabe <code>'get_movie_ratings'</code> an die Indexierungsfunktion.</p>index_ratings_operator = PythonOperator(
   task_id='index_movie_ratings',
   python_callable=index_movie_ratings_task,
   op_args=["{{ task_instance.xcom_pull(task_ids='get_movie_ratings') }}"]
)<p>Wenn die Validierung einen Fehler anzeigt, fährt der DAG mit einer Fehlerbenachrichtigungsaufgabe fort. In diesem Beispiel geben wir einfach eine Meldung aus, aber in einem realen Szenario könnten wir Warnmeldungen konfigurieren, um über die Fehler zu informieren.</p>failed_get_rating_operator = PythonOperator(
   task_id='failed_get_rating_operator',
   python_callable=lambda: print('Ratings were False, skipping indexing.')
)<p>Abschließend definieren wir die Aufgabenabhängigkeiten und stellen sicher, dass sie in der richtigen Reihenfolge ausgeführt werden:</p>get_ratings_operator &gt;&gt; validate_result &gt;&gt; [index_ratings_operator, failed_get_rating_operator]<p>Hier folgt nun der vollständige Code unseres DAG:</p>"""
DAG update Rating Movies
"""
import ast
import random

from airflow import DAG
from datetime import datetime

from airflow.operators.python import PythonOperator, BranchPythonOperator
from airflow.providers.elasticsearch.hooks.elasticsearch import ElasticsearchPythonHook


def index_movie_ratings_task(movies):
   es_hook = ElasticsearchPythonHook(hosts=None,
                                     es_conn_args={
                                         "cloud_id": "cloud_id"
                                         "api_key": "api-key"
                                     })
   es_client = es_hook.get_conn
   actions = []
   for movie in ast.literal_eval(movies):
       actions.append(
           {
               "update": {
                   "_id": movie["id"],
                   "_index": "movies"
               }
           }
       )
       actions.append(
           {
               "doc": {
                   "rating": movie["rating"]
               },
               "doc_as_upsert": True
           }
       )
   result = es_client.bulk(operations=actions)
   print(f"Ingestion completed.")
   print(result)
   return True


def get_movie_ratings_task():
   movies = [
       {"id": i, "rating": round(random.uniform(1, 10), 1)}
       for i in range(1, 100)
   ]
   return movies

def validate_result(result):
   if not result:
       return 'failed_get_rating_operator'
   else:
       return 'index_movie_ratings'


with DAG(
       dag_id="update_ratings_movies_2024",
       start_date=datetime(2024, 12, 29),
       schedule="@daily",
       doc_md=__doc__,
):
   get_ratings_operator = PythonOperator(
       task_id='get_movie_ratings',
       python_callable=get_movie_ratings_task
   )

   validate_result = BranchPythonOperator(
       task_id='validate_result',
       python_callable=validate_result,
       op_args=["{{ task_instance.xcom_pull(task_ids='get_movie_ratings') }}"],
       provide_context=True
   )

   index_ratings_operator = PythonOperator(
       task_id='index_movie_ratings',
       python_callable=index_movie_ratings_task,
       op_args=["{{ task_instance.xcom_pull(task_ids='get_movie_ratings') }}"]
   )

   failed_get_rating_operator = PythonOperator(
       task_id='failed_get_rating_operator',
       python_callable=lambda: print('Ratings were False, skipping indexing.')
   )

get_ratings_operator &gt;&gt; validate_result &gt;&gt; [index_ratings_operator, failed_get_rating_operator]<h2>Visualisierung der DAG-Ausführung</h2><p>In der Apache Airflow-Oberfläche können wir die Ausführung der DAGs visualisieren. Gehen Sie einfach auf die Registerkarte „DAGs“ und suchen Sie den von Ihnen erstellten DAG.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9c5de210a5a264ad/6a17dfd00b0bed0290dd34cf/905b9191c4e3191e8b5608174d4c555370bf25eb-1600x760.png" alt="Visualisieren Sie die Ausführung der DAGs in der Apache Airflow-Schnittstelle mit Elasticsearch." /><p>Im Folgenden können wir die Ausführung der Aufgaben und ihre jeweiligen Status visualisieren. Durch die Auswahl einer Ausführung für ein bestimmtes Datum können wir auf die Protokolle der einzelnen Aufgaben zugreifen. Beachten Sie, dass wir in der <strong><code>index_movie_ratings</code></strong> -Aufgabe die Indexierungsergebnisse im Index sehen können und dass sie erfolgreich abgeschlossen wurde.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0beddf311a808d24/6a17dfd2033c8d76de6bb0ba/73c3f738d27500cf153377bedf1aa2b67a94a8c8-1600x648.png" alt="Visualisieren Sie die Ausführung der Aufgaben und deren Status in Apache Airflow mit Elasticsearch." /><p>In den anderen Registerkarten können Sie auf zusätzliche Informationen zu den Aufgaben und dem DAG zugreifen, die Ihnen bei der Analyse und Lösung potenzieller Probleme helfen.</p><h2>Fazit</h2><p>In diesem Artikel haben wir gezeigt, wie man Apache Airflow mit Elasticsearch integriert, um eine Datenerfassungslösung zu erstellen. Wir haben gezeigt, wie man den DAG konfiguriert, die Aufgaben definiert, die für das Abrufen, Validieren und Indizieren von Filmdaten zuständig sind, und wie man die Ausführung dieser Aufgaben in der Airflow-Oberfläche überwacht und visualisiert.</p><p>Dieser Ansatz lässt sich leicht an verschiedene Datentypen und Arbeitsabläufe anpassen, wodurch Airflow zu einem nützlichen Werkzeug für die Orchestrierung von Datenpipelines in unterschiedlichen Szenarien wird.</p><h2>Referenzen</h2><p>Apache AirFlow</p><p><a href="https://airflow.apache.org/">https://airflow.apache.org/</a></p><p>Apache Airflow mit Docker installieren</p><p><a href="https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html">https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html</a></p><p>Elasticsearch Python Hook</p><p><a href="https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/stable/hooks/elasticsearch_python_hook.html">https://airflow.apache.org/docs/apache-airflow-providers-elasticsearch/stable/hooks/elasticsearch_python_hook.html</a></p><p>Python-Operator</p><p><a href="https://airflow.apache.org/docs/apache-airflow/stable/howto/operator/python.html">https://airflow.apache.org/docs/apache-airflow/stable/howto/operator/python.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/apache-airflow-elasticsearch-ingest-data</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/apache-airflow-elasticsearch-ingest-data</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt28475ace97d1d989/6a1704c9286714d6dd93e1ec/5d4b47ac5d2ba453fc19dcc15efa2aed5f55d88b-1440x1355.png" length="0" type="image/png"/>
    <pubDate>Fri, 17 Jan 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Wie man Daten über Kafka in Elasticsearch einliest]]></title>
    <description><![CDATA[Eine Schritt-für-Schritt-Anleitung zur Integration von Apache Kafka mit Elasticsearch für effiziente Datenerfassung, -indizierung und -visualisierung mit Python, Docker Compose und Kafka Connect.]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel zeigen wir, wie man Apache Kafka mit Elasticsearch zur Datenerfassung und -indizierung integriert. Wir geben einen Überblick über Kafka, sein Konzept von Produzenten und Konsumenten und erstellen einen Log-Index, in dem Nachrichten über Apache Kafka empfangen und indexiert werden. Das Projekt wurde in Python implementiert, und der Code ist auf <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/elasticsearch-through-apache-kafka">GitHub</a> verfügbar.</p><h3><strong>Voraussetzungen</strong></h3><ul><li><p>Docker und Docker Compose: Stellen Sie sicher, dass Docker und Docker Compose auf Ihrem Rechner installiert sind.</p></li><li><p>Python 3.x: Zum Ausführen der Producer- und Consumer-Skripte.</p></li></ul><h3><strong>Einführung in Apache Kafka</strong></h3><p>Apache Kafka ist eine verteilte Streaming-Plattform, die hohe Skalierbarkeit und Verfügbarkeit sowie Fehlertoleranz ermöglicht. In Kafka erfolgt die Datenverwaltung über die Hauptkomponenten:</p><ul><li><p><strong>Broker</strong>: zuständig für die Speicherung und Verteilung von Nachrichten zwischen Produzenten und Konsumenten.</p></li><li><p><strong>Zookeeper</strong>: verwaltet und koordiniert die Kafka-Broker und kontrolliert den Zustand des Clusters, die Partitionsleiter und die Verbraucherinformationen.</p></li><li><p><strong>Themen</strong>: Kanäle, auf denen Daten veröffentlicht und zur Nutzung gespeichert werden.</p></li><li><p><strong>Konsumenten und Produzenten</strong>: Während Produzenten Daten an die Themen senden, rufen Konsumenten diese Daten ab.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4aae32304d7417f6/6a17f7be577262b47c1bcdac/89a37243baec48bbdfa85e3298fc91082322ed4e-1600x868.png" alt="Diagramm Apache Kafka" /><p>Diese Komponenten arbeiten zusammen und bilden das Kafka-Ökosystem, das ein robustes Framework für das Datenstreaming bietet.</p><h3><strong>Projektstruktur</strong></h3><p>Um den Datenerfassungsprozess zu verstehen, haben wir ihn in Phasen unterteilt:</p><ul><li><p><strong>Infrastrukturbereitstellung</strong>: Einrichtung der Docker-Umgebung zur Unterstützung von Kafka, Elasticsearch und Kibana.</p></li><li><p><strong>Producer-Erstellung</strong>: Implementierung des Kafka-Producers, der Daten an das Logs-Topic sendet.</p></li><li><p><strong>Consumer Creation</strong>: Entwicklung des Kafka-Consumers zum Lesen und Indizieren von Nachrichten in Elasticsearch.</p></li><li><p><strong>Aufnahmevalidierung</strong>: Überprüfung und Validierung der gesendeten und empfangenen Daten.</p></li></ul><h3><strong>Infrastrukturkonfiguration mit Docker Compose</strong></h3><p>Wir haben Docker Compose verwendet, um die notwendigen Dienste zu konfigurieren und zu verwalten. Nachfolgend finden Sie den Docker Compose-Code, der die für die Integration von Apache Kafka, Elasticsearch und Kibana erforderlichen Dienste einrichtet und so einen Datenaufnahmeprozess sicherstellt.</p>version: "3"

services:

  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    container_name: zookeeper
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181

  kafka:
    image: confluentinc/cp-kafka:latest
    container_name: kafka
    depends_on:
      - zookeeper
    ports:
      - "9092:9092"
      - "9094:9094"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST:${HOST_IP}:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.15.1
    container_name: elasticsearch-8.15.1
    environment:
      - node.name=elasticsearch
      - xpack.security.enabled=false
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - ./elasticsearch:/usr/share/elasticsearch/data
    ports:
      - 9200:9200

  kibana:
    image: docker.elastic.co/kibana/kibana:8.15.1
    container_name: kibana-8.15.1
    ports:
      - 5601:5601
    environment:
      ELASTICSEARCH_URL: http://elasticsearch:9200
      ELASTICSEARCH_HOSTS: '["http://elasticsearch:9200"]'<p>Sie können direkt über das Elasticsearch Labs <a href="https://github.com/andreluiz1987/elasticsearch-labs/tree/supporting-blog/elasticsearch-apache-kafka/supporting-blog-content/elasticsearch-through-apache-kafka">GitHub-</a> Repository auf die Datei zugreifen.</p><h3><strong>Datenübertragung mit dem Kafka Producer</strong></h3><p>Der Produzent ist für das Senden von Nachrichten an das Log-Thema verantwortlich. Durch das Senden von Nachrichten in Stapeln wird die Netzwerknutzungseffizienz gesteigert. Optimierungen sind mit den Einstellungen <code>batch_size</code> und <code>linger_ms</code> möglich, die die Anzahl bzw. die Latenz der Stapel steuern. Die Konfiguration <code>acks='all'</code> gewährleistet, dass Nachrichten dauerhaft gespeichert werden, was für wichtige Protokolldaten unerlässlich ist.</p>producer = KafkaProducer(
   bootstrap_servers=['localhost:9092'],  # Specifies the Kafka server to connect
   value_serializer=lambda x: json.dumps(x).encode('utf-8'),  # Serializes data as JSON and encodes it to UTF-8 before sending
   batch_size=16384,     # Sets the maximum batch size in bytes (here, 16 KB) for buffered messages before sending
   linger_ms=10,         # Sets the maximum delay (in milliseconds) before sending the batch
   acks='all'            # Specifies acknowledgment level; 'all' ensures message durability by waiting for all replicas to acknowledge
)


def generate_log_message():
   levels = ["INFO", "WARNING", "ERROR", "DEBUG"]
   messages = [
       "User login successful",
       "User login failed",
       "Database connection established",
       "Database connection failed",
       "Service started",
       "Service stopped",
       "Payment processed",
       "Payment failed"
   ]
   log_entry = {
       "level": random.choice(levels),
       "message": random.choice(messages),
       "timestamp": time.time()
   }
   return log_entry

def send_log_batches(topic, num_batches=5, batch_size=10):
   for i in range(num_batches):
       logger.info(f"Sending batch {i + 1}/{num_batches}")
       for  in range(batch_size):
           log_message = generate_log_message()
           producer.send(topic, value=log_message)
       producer.flush()


if __name__ == "__main__":
   topic = "logs"
   send_log_batches(topic)
   producer.close()<p>Beim Starten des Producers werden die Nachrichten in Batches an das Topic gesendet, wie unten dargestellt:</p>INFO:kafka.conn:Set configuration …
INFO:log_producer:Sending batch 1/5 
INFO:log_producer:Sending batch 2/5
INFO:log_producer:Sending batch 3/5
INFO:log_producer:Sending batch 4/5<h3><strong>Konsum und Indizierung von Daten mit dem Kafka Consumer</strong></h3><p>Der Consumer ist so konzipiert, dass er Nachrichten effizient verarbeitet, indem er Batches aus dem Logs-Topic empfängt und diese in Elasticsearch indexiert. Mit <code>auto_offset_reset='latest'</code> wird sichergestellt, dass der Consumer mit der Verarbeitung der neuesten Nachrichten beginnt und die älteren ignoriert, und <code>max_poll_records=10</code> begrenzt den Batch auf 10 Nachrichten. Bei <code>fetch_max_wait_ms=2000</code> wartet der Konsument bis zu 2 Sekunden, um genügend Nachrichten zu sammeln, bevor er den Batch verarbeitet.</p><p>Im Hauptzyklus verarbeitet der Consumer die Logmeldungen, speichert sie in Elasticsearch und indexiert sie, um eine kontinuierliche Datenaufnahme zu gewährleisten.</p>consumer = KafkaConsumer(
   'logs',                               
   bootstrap_servers=['localhost:9092'],
   auto_offset_reset='latest',            # Ensures reading from the latest offset if the group has no offset stored
   enable_auto_commit=True,               # Automatically commits the offset after processing
   group_id='log_consumer_group',         # Specifies the consumer group to manage offset tracking
   max_poll_records=10,                   # Maximum number of messages per batch
   fetch_max_wait_ms=2000                 # Maximum wait time to form a batch (in ms)
)

def create_bulk_actions(logs):
   for log in logs:
       yield {
           "_index": "logs",
           "_source": {
               'level': log['level'],
               'message': log['message'],
               'timestamp': log['timestamp']
           }
       }

if __name__ == "__main__":
   try:
       print("Starting message processing…")
       while True:

           messages = consumer.poll(timeout_ms=1000)  # Poll receive messages

           # process each batch messages
           for _, records in messages.items():
               logs = [json.loads(record.value) for record in records]
               bulk_actions = create_bulk_actions(logs)
               response = helpers.bulk(es, bulk_actions)
               print(f"Indexed {response[0]} logs.")
   except Exception as e:
       print(f"Erro: {e}")
   finally:
       consumer.close()
       print(f"Finish")<h3><strong>Datenvisualisierung in Kibana</strong></h3><p>Mit Kibana können wir die von Kafka aufgenommenen und in Elasticsearch indexierten Daten untersuchen und validieren. Durch den Zugriff auf <strong>die Entwicklertools</strong> in Kibana können Sie die indizierten Nachrichten anzeigen und überprüfen, ob die Daten den Erwartungen entsprechen. Wenn beispielsweise unser Kafka-Producer 5 Batches mit jeweils 10 Nachrichten sendet, sollten wir insgesamt 50 Datensätze im Index sehen.</p><p>Um die Daten zu überprüfen, können Sie die folgende Abfrage im Abschnitt <strong>„Entwicklertools“</strong> verwenden:</p>GET /logs/_search
{
  "query": {
    "match_all": {}
  }
}<p>Abwehr:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc15fb278fe6f984e/6a17f7c0b1e1131ac279f404/f44f95fc27bba50991412d5c7e7728519b9bdec4-688x1024.png" alt="Antwort zur Datenprüfung – Kafka &amp; Elasticsearch​" /><p>Darüber hinaus bietet Kibana die Möglichkeit, Visualisierungen und Dashboards zu erstellen, die die Analyse intuitiver und interaktiver gestalten können. Nachfolgend sehen Sie einige Beispiele der von uns erstellten Dashboards und Visualisierungen, die die Daten in verschiedenen Formaten veranschaulichen und so unser Verständnis der verarbeiteten Informationen verbessern.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltabc2856c9feedc47/6a17f7c13e9e4522bfba1651/a18e0ebb543e929136d4786651bc6cee32fa69bc-1600x470.png" alt="Kibana-Visualisierung – Kafka &amp; Elasticsearch​" /><h3><strong>Datenaufnahme mit Kafka Connect</strong></h3><p>Kafka Connect ist ein Dienst, der die Integration zwischen Datenquellen und Zielen (Senken) wie Datenbanken oder Dateisystemen erleichtert. Es arbeitet mit vordefinierten Konnektoren, die den Datentransfer automatisch abwickeln. In unserem Fall fungiert Elasticsearch als Datensenke.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt53e3acaf62e7dbed/6a17f7c3577262c5151bcdb0/52a6982c864fdc04cb7a8a5fb02e67dca0ba8226-1600x819.png" alt="Datenerfassung mit Kafka Connect" /><p>Mit Kafka Connect können wir den Datenaufnahmeprozess vereinfachen und die Notwendigkeit eliminieren, den Datenaufnahme-Workflow manuell in Elasticsearch zu implementieren. Mit dem passenden Konnektor ermöglicht Kafka Connect die direkte Indizierung von Daten, die an ein Kafka-Topic gesendet werden, in Elasticsearch – mit minimalem Einrichtungsaufwand und ohne zusätzliche Programmierung.</p><h4><strong>Arbeiten mit Kafka Connect</strong></h4><p>Um Kafka Connect zu implementieren, fügen wir den<a href="https://github.com/andreluiz1987/es-apache-kafka/blob/main/docker-compose.yml#L31"> kafka-connect-Dienst </a>zu unserem Docker Compose-Setup hinzu. Ein wichtiger Bestandteil dieser Konfiguration ist die Installation des Elasticsearch-Connectors, der für die Datenindizierung zuständig ist.</p><p>Nach der Konfiguration des Dienstes und der Erstellung des Kafka Connect-Containers wird eine Konfigurationsdatei für den Elasticsearch-Connector benötigt. Diese Datei definiert wichtige Parameter wie zum Beispiel:</p><ul><li><p><code>connection.url</code>: Verbindungs-URL für Elasticsearch.</p></li><li><p><code>topics</code>: Das Kafka-Thema, das der Connector überwachen wird (in diesem Fall "logs").</p></li><li><p><code>type.name</code>: Dokumenttyp in Elasticsearch (typischerweise _doc).</p></li><li><p><code>value.converter</code>: Konvertiert Kafka-Nachrichten in das JSON-Format.</p></li><li><p><code>value.converter.schemas.enable</code>: Gibt an, ob das Schema einbezogen werden soll.</p></li><li><p><code>schema.ignore</code> und <code>key.ignore</code>: Einstellungen zum Ignorieren von Kafka-Schemas und -Schlüsseln während der Indizierung.</p></li></ul><p>Nachfolgend der Befehl <code>curl</code> zum Erstellen des Elasticsearch-Connectors in Kafka Connect:</p>curl --location '{{url}}/connectors' \
--header 'Content-Type: application/json' \
--data '{
    "name": "elasticsearch-sink-connector",
    "config": {
        "connector.class": "io.confluent.connect.elasticsearch.ElasticsearchSinkConnector",
        "topics": "logs",
        "connection.url": "http://elasticsearch:9200",
        "type.name": "_doc",
        "value.converter": "org.apache.kafka.connect.json.JsonConverter",
        "value.converter.schemas.enable": "false",
        "schema.ignore": "true",
        "key.ignore": "true"
    }
}'<p>Mit dieser Konfiguration beginnt Kafka Connect automatisch mit der Erfassung der an das Topic "logs" gesendeten Daten und deren Indizierung in Elasticsearch. Dieser Ansatz ermöglicht die vollautomatische Datenerfassung und -indizierung ohne zusätzlichen Programmieraufwand und vereinfacht so den gesamten Integrationsprozess.</p><h3><strong>Fazit</strong></h3><p>Durch die Integration von Kafka und Elasticsearch entsteht eine leistungsstarke Pipeline für die Datenerfassung und -analyse in Echtzeit. Dieser Leitfaden bietet einen grundlegenden Ansatz für den Aufbau einer robusten Datenerfassungsarchitektur mit nahtloser Visualisierung und Analyse in Kibana, die sich zukünftig an komplexere Anforderungen anpassen lässt.</p><p>Darüber hinaus vereinfacht die Verwendung von Kafka Connect die Integration zwischen Kafka und Elasticsearch zusätzlich, wodurch die Notwendigkeit von zusätzlichem Code zur Verarbeitung und Indizierung von Daten entfällt. Kafka Connect ermöglicht es, Daten, die an ein bestimmtes Thema gesendet werden, mit minimalem Konfigurationsaufwand automatisch in Elasticsearch zu indizieren.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-apache-kafka-ingest-data</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-apache-kafka-ingest-data</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt53e3acaf62e7dbed/6a17f7c3577262c5151bcdb0/52a6982c864fdc04cb7a8a5fb02e67dca0ba8226-1600x819.png" length="0" type="image/png"/>
    <pubDate>Tue, 24 Dec 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Wie man Daten über Apache Camel in Elasticsearch aufnimmt]]></title>
    <description><![CDATA[Lernen Sie anhand eines praktischen Beispiels, wie Sie Daten mithilfe von Apache Camel in Elasticsearch einlesen.]]></description>
    <content:encoded><![CDATA[<p>Die Datenaufnahme in Elasticsearch mit Apache Camel ist ein Prozess, der die Robustheit einer Suchmaschine mit der Flexibilität eines Integrationsframeworks verbindet. In diesem Artikel werden wir untersuchen, wie Apache Camel die Datenaufnahme in Elasticsearch vereinfachen und optimieren kann. Um diese Funktionalität zu veranschaulichen, werden wir eine einführende Anwendung implementieren, die Schritt für Schritt demonstriert, wie man Apache Camel konfiguriert und verwendet, um Daten an Elasticsearch zu senden.</p><h2>Was ist Apache Camel?</h2><p>Apache Camel ist ein Open-Source-Integrationsframework, das die Verbindung verschiedener Systeme vereinfacht und es Entwicklern ermöglicht, sich auf die Geschäftslogik zu konzentrieren, ohne sich um die Komplexität der Systemkommunikation kümmern zu müssen. Das zentrale Konzept in Camel sind „Routen“, die den Weg definieren, den eine Nachricht vom Ursprung zum Ziel zurücklegt, einschließlich potenzieller Zwischenschritte wie Transformationen, Validierungen und Filterungen.</p><h3>Apache Camel-Architektur</h3><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt05652327efd4d5d1/6a17e6dafbc5f8a588491a8b/bef8145623a8fa80f929f9faa57ce0c460be2d0b-884x458.png" alt="Apache Camel-Architektur" /><p>Camel verwendet „Komponenten“, um Verbindungen zu verschiedenen Systemen und Protokollen wie Datenbanken und Messaging-Diensten herzustellen, sowie „Endpunkte“, um die Ein- und Austrittspunkte von Nachrichten darzustellen. Diese Konzepte bieten ein modulares und flexibles Design, wodurch die Konfiguration und Verwaltung komplexer Integrationen effizienter und skalierbarer wird.</p><h2>Verwendung von Elasticsearch und Apache Camel</h2><p>Wir zeigen Ihnen, wie Sie eine einfache Java-Anwendung konfigurieren, die Apache Camel verwendet, um Daten in einen Elasticsearch-Cluster einzuspeisen. Die Prozesse zum Erstellen, Aktualisieren und Löschen von Daten in Elasticsearch mithilfe von in Apache Camel definierten Routen werden ebenfalls behandelt.</p><h3>1. Hinzufügen von Abhängigkeiten</h3><p>Der erste Schritt bei der Konfiguration dieser Integration besteht darin, die notwendigen Abhängigkeiten zur <code>pom.xml</code> -Datei Ihres Projekts hinzuzufügen. Dies umfasst die Apache Camel- und Elasticsearch-Bibliotheken. Wir werden die neue Java API Client-Bibliothek verwenden, daher müssen wir die Komponente <code>camel-elasticsearch</code> importieren, und zwar in der Version, die mit der der Bibliothek <code>camel-core</code> übereinstimmen muss.</p><p>Wenn Sie den Java Low Level Rest Client verwenden möchten, müssen Sie die Elasticsearch Low Level Rest Client-Komponente verwenden.</p>&lt;dependency&gt;
   &lt;groupId&gt;org.apache.camel&lt;/groupId&gt;
   &lt;artifactId&gt;camel-core&lt;/artifactId&gt;
   &lt;version&gt;4.7.0&lt;/version&gt;
&lt;/dependency&gt;

&lt;dependency&gt;
   &lt;groupId&gt;org.apache.camel&lt;/groupId&gt;
   &lt;artifactId&gt;camel-elasticsearch&lt;/artifactId&gt;
   &lt;version&gt;4.7.0&lt;/version&gt;
&lt;/dependency&gt;

&lt;dependency&gt;
   &lt;groupId&gt;org.apache.camel&lt;/groupId&gt;
   &lt;artifactId&gt;camel-jackson&lt;/artifactId&gt;
   &lt;version&gt;4.7.0&lt;/version&gt;
&lt;/dependency&gt;

&lt;dependency&gt;
   &lt;groupId&gt;co.elastic.clients&lt;/groupId&gt;
   &lt;artifactId&gt;elasticsearch-java&lt;/artifactId&gt;
   &lt;version&gt;8.14.3&lt;/version&gt;
&lt;/dependency&gt;
<h3>2. Konfigurieren und Ausführen des Camel-Kontexts</h3><p>Die Konfiguration beginnt mit der Erstellung eines neuen Camel-Kontexts mithilfe der Klasse <code>DefaultCamelContext</code> , die als Basis für die Definition und Ausführung von Routen dient. Als Nächstes konfigurieren wir die Elasticsearch-Komponente, die es Apache Camel ermöglicht, mit einem Elasticsearch-Cluster zu interagieren. Die <code>ESlasticsearchComponent</code> -Instanz ist so konfiguriert, dass sie eine Verbindung zur Adresse <code>localhost:9200</code> herstellt. Dies ist die Standardadresse für einen lokalen Elasticsearch-Cluster. Für eine Umgebungskonfiguration, die eine Authentifizierung erfordert, sollten Sie die Dokumentation zur Konfiguration der Komponente und zur Aktivierung der Basisauthentifizierung lesen, die unter dem Titel <strong>„Komponente konfigurieren und Basisauthentifizierung aktivieren“</strong> bezeichnet wird.</p>public class ESComponent {

    public static ElasticsearchComponent getInstance() {
        var elasticsearch = new ElasticsearchComponent();
        elasticsearch.setHostAddresses("localhost:9200");
        return elasticsearch;
    }

    public static String getName() {
        return "elasticsearch";
    }
}
<p>Diese Komponente wird dann dem Camel-Kontext hinzugefügt, wodurch die definierten Routen diese Komponente nutzen können, um Operationen in Elasticsearch durchzuführen.</p>try (var context = new DefaultCamelContext()) {
   context.addComponent(ESComponent.getName(), ESComponent.getInstance());
   context.addRoutes(new OperationBulkRoute());
   context.start();
}
<p>Anschließend werden die Routen dem Kontext hinzugefügt. Wir werden Routen für die Massenindizierung, Aktualisierung und Löschung von Dokumenten erstellen.</p><h3>3. Konfiguration von Camel-Routen</h3><h4>Datenindizierung</h4><p>Die erste Route, die wir konfigurieren werden, dient der Datenindizierung. Wir werden eine JSON-Datei verwenden, die einen Filmkatalog enthält. Die Route wird so konfiguriert, dass die unter <a href="https://gist.github.com/andreluiz1987/40756874b5fbea0a29586f9376d7f1f4"><code>src/main/resources/movies.json</code></a> befindliche Datei gelesen, der JSON-Inhalt in Java-Objekte deserialisiert und anschließend eine Aggregationsstrategie angewendet wird, um mehrere Nachrichten zu einer einzigen zusammenzufassen, wodurch Batch-Operationen in Elasticsearch ermöglicht werden. Es wurde eine Größe von 500 Elementen pro Nachricht konfiguriert, d. h., der Massenindex indexiert jeweils 500 Filme.</p><p>Route Elasticsearch Operation Bulk</p>String URI_BULK_OPERATION = String
       .format("elasticsearch://elasticsearch?operation=%s&amp;indexName=%s",
               IndexOperationConfig.BULK_OPERATION,
               INDEX_NAME);
public class OperationBulkRoute extends RouteBuilder {
   private static final Log log = LogFactory.getLog(OperationBulkRoute.class);
   private static final int BULK_SIZE = 500;

   @Override
   public void configure() {
       from("file:src/main/resources?fileName=movies.json&amp;noop=true")
               .routeId("route-bulk-ingest")
               .unmarshal().json()
               .split(body())
               .aggregate(constant(true), new BulkAggregationStrategy())
               .completionSize(BULK_SIZE)
               .to(URI_BULK_OPERATION)
               .process(exchange -&gt; {
                   var body = exchange.getIn().getBody(String.class);
                   log.info(String.format("Response: %s", body));
               })
               .end();
   }
}
<p>Der Dokumentenstapel wird an den Bulk-Operations-Endpunkt von Elasticsearch gesendet. Dieser Ansatz gewährleistet Effizienz und Geschwindigkeit bei der Verarbeitung großer Datenmengen.</p><h4>Datenaktualisierung</h4><p>Der nächste Schritt besteht darin, die Dokumente zu aktualisieren. Im vorherigen Schritt haben wir einige Filme indexiert. Nun erstellen wir neue Routen, um anhand des Referenzcodes nach einem Dokument zu suchen und anschließend das Bewertungsfeld zu aktualisieren.</p><p>Wir richten einen Camel-Kontext <code>(DefaultCamelContext)</code> ein, in dem eine Elasticsearch-Komponente registriert und eine benutzerdefinierte Route IngestionRoute hinzugefügt wird. Der Vorgang beginnt mit dem Senden des Dokumentcodes über die ProducerTemplate, wodurch die Route vom Endpunkt direct:update-ingestion gestartet wird.</p>try (var context = new DefaultCamelContext()) {
    context.addComponent(ESComponent.getName(), ESComponent.getInstance());
    context.addRoutes(new IngestionRoute());
    context.start();
    ProducerTemplate producerTemplate = context.createProducerTemplate();
    producerTemplate.sendBody("direct:update-ingestion", documentCode);
    Thread.sleep(5000);
}
<p>Als nächstes haben wir die IngestionRoute, die der Eingabeendpunkt für diesen Datenfluss ist. Die Route führt mehrere nacheinander ausgeführte Operationen durch. Zunächst wird in Elasticsearch eine Suche durchgeführt, um das Dokument anhand des Codes <code>(direct:search-by-id)</code> zu finden. Der SearchByCodeProcessor stellt die Abfrage auf Basis des Codes zusammen. Anschließend wird das abgerufene Dokument vom UpdateRatingProcessor verarbeitet, der das Ergebnis in Movie-Objekte umwandelt, die Filmbewertung auf einen bestimmten Wert aktualisiert und das aktualisierte Dokument für die Rücksendung an Elasticsearch zur Aktualisierung vorbereitet.</p>public class IngestionRoute extends RouteBuilder {
    private static final Log log = LogFactory.getLog(IngestionRoute.class);

    @Override
    public void configure() throws Exception {

        from("direct:update-ingestion")
                .pipeline()
                .to("direct:search-by-id")
                .to(URI_SEARCH_OPERATION)
                .to("direct:update-rating")
                .to(URI_UPDATE_OPERATION)
                .process(exchange -&gt; {
                    var body = exchange.getIn().getBody(String.class);
                    log.info(String.format("Response: %s", body));
                })
                .end();

        from("direct:search-by-id")
                .process(new SearchByCodeProcessor());

        from("direct:update-rating")
                .process(new UpdateRatingProcessor());
    }
}
<p>Der <code>SearchByCodeProcessor</code> -Prozessor wurde nur für die Ausführung der Suchanfrage konfiguriert:</p>public class SearchByCodeProcessor implements Processor {
    @Override
    public void process(Exchange exchange) throws Exception {
        var code = exchange.getIn().getBody();

        String query = "{\n" +
                "  \"query\": {\n" +
                "   \"term\": {\n" +
                "     \"code\": {\n" +
                "       \"value\":" + code + "\n" +
                "     }\n" +
                "   }\n" +
                "  }\n" +
                "}";
        exchange.setProperty("document_code", code);
        exchange.getIn().setBody(query);
    }
}
<p>Der <code>UpdateRatingProcessor</code> -Prozessor ist für die Aktualisierung des Bewertungsfelds zuständig.</p>public class UpdateRatingProcessor implements Processor {

    private final ObjectMapper objectMapper;

    public UpdateRatingProcessor() {
        this.objectMapper = new ObjectMapper();
        this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    @Override
    public void process(Exchange exchange) throws Exception {

        HitsMetadata response = exchange.getIn().getBody(HitsMetadata.class);
        var code = Long.parseLong(exchange.getProperty("document_code").toString());

        if (response != null &amp;&amp; response.hits() != null) {

            var documents = parseToMovies(response);

            var optionalMovie = documents.stream()
                    .filter(document -&gt; code == (document.getSource().getCode())).findAny();

            optionalMovie.ifPresent(document -&gt; {
                document.getSource().setRating(13.0);
                Map&lt;String, Object&gt; updateMap = new HashMap&lt;&gt;();
                updateMap.put("doc", document.getSource());
                exchange.getIn().setHeader("indexId", document.getId());
                exchange.getIn().setBody(updateMap);
            });
        }
    }
<h4>Datenlöschung</h4><p>Abschließend wird der Weg zum Löschen von Dokumenten konfiguriert. Hier löschen wir ein Dokument anhand seiner ID. Um in Elasticsearch ein Dokument zu löschen, benötigen wir die Dokumentkennung, den Index, in dem das Dokument gespeichert ist, und müssen eine Löschanforderung ausführen. In Apache Camel führen wir diese Operation durch, indem wir eine neue Route erstellen, wie unten gezeigt.</p><p>Die Route beginnt am Endpunkt direct:op-delete, der als Einstiegspunkt dient. Wenn ein Dokument gelöscht werden muss, wird seine Kennung <code>(_id)</code> im Nachrichtentext empfangen. Die Route setzt dann den IndexId-Header mit dem Wert dieser Kennung mithilfe von einfachem<code>("${body}")</code>, wodurch die _id aus dem Nachrichtentext extrahiert wird.</p>public class OperationDeleteRoute extends RouteBuilder {
   private static final Log log = LogFactory.getLog(OperationDeleteRoute.class);

   @Override
   public void configure() {
       from("direct:op-delete")
               .routeId("route-delete")
               .setHeader("indexId", simple("${body}"))
               .to(URI_DELETE_OPERATION)
               .process(exchange -&gt; {
                   var body = exchange.getIn().getBody(String.class);
                   log.info(String.format("Response: %s", body));
               })
               .end();
       ;
   }
}
String URI_DELETE_OPERATION = String
       .format("elasticsearch://elasticsearch?operation=%s&amp;indexName=%s",
               IndexOperationConfig.DELETE_OPERATION,
               INDEX_NAME);
<p>Schließlich wird die Nachricht an den durch URI_DELETE_OPERATION angegebenen Endpunkt weitergeleitet, der eine Verbindung zu Elasticsearch herstellt, um die Dokumentenlöschung im entsprechenden Index durchzuführen.
Nachdem wir die Route erstellt haben, können wir einen Camel-Kontext <code>(DefaultCamelContext)</code> erstellen, der so konfiguriert ist, dass er die Elasticsearch-Komponente enthält.</p>try (var context = new DefaultCamelContext()) {
   context.addComponent(ESComponent.getName(), ESComponent.getInstance());
   context.addRoutes(new OperationDeleteRoute());
   context.start();
   ProducerTemplate producerTemplate = context.createProducerTemplate();
   producerTemplate.sendBody("direct:op-delete", documentId);
}
<p>Als nächstes wird die durch die Klasse <code>OperationDeleteRoute</code> definierte Löschroute zum Kontext hinzugefügt. Nachdem der Kontext initialisiert wurde, wird ein <code>ProducerTemplate</code> verwendet, um die Kennung des zu löschenden Dokuments an den <code>direct:op-delete</code> Endpunkt zu übergeben, wodurch die Löschroute ausgelöst wird.</p><h2>Fazit</h2><p>Die Integration zwischen Apache Camel und Elasticsearch ermöglicht eine robuste und effiziente Datenaufnahme, indem die Flexibilität von Camel genutzt wird, um Routen zu definieren, die verschiedene Datenmanipulationsszenarien wie Indizierung, Aktualisierung und Löschung bewältigen können. Mit diesem Setup können Sie komplexe Prozesse skalierbar orchestrieren und automatisieren und so sicherstellen, dass Ihre Daten in Elasticsearch effizient verwaltet werden. Dieses Beispiel demonstrierte, wie diese Werkzeuge zusammen verwendet werden können, um eine effiziente und anpassungsfähige Lösung für die Datenerfassung zu schaffen.</p><h2>Referenzen</h2><ul><li><p><a href="https://camel.apache.org/manual/">Apache Camel</a></p></li><li><p><a href="https://camel.apache.org/manual/architecture.html">Apache Camel-Architektur</a></p></li><li><p><a href="https://camel.apache.org/components/4.4.x/eips/aggregate-eip.html">Aggregate Apache Camel</a></p></li><li><p><a href="https://camel.apache.org/components/4.4.x/file-component.html">Dateikomponente</a></p></li><li><p><a href="https://camel.apache.org/components/4.4.x/elasticsearch-component.html">Elasticsearch-Komponente</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-apache-camel-ingest-data</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-apache-camel-ingest-data</guid>
    <category><![CDATA[Index-Daten]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt05652327efd4d5d1/6a17e6dafbc5f8a588491a8b/bef8145623a8fa80f929f9faa57ce0c460be2d0b-884x458.png" length="0" type="image/png"/>
    <pubDate>Mon, 09 Sep 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>