<?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[Andre Luiz - 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[Andre Luiz - 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/author/andre-luiz</link>
    </image>
    <link>https://www.elastic.co/de/search-labs/author/andre-luiz</link>
    <atom:link href="https://www.elastic.co/de/search-labs/rss/author/andre-luiz.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[de]]></language>
    <lastBuildDate>Tue, 22 Sep 2026 16:54:18 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Zuordnung von Einbettungen zu Elasticsearch-Feldtypen: semantic_text, dense_vector, sparse_vector]]></title>
    <description><![CDATA[Erörterung, wie und wann semantic_text, dense_vector oder sparse_vector verwendet werden und wie diese mit der Einbettungsgenerierung zusammenhängen.]]></description>
    <content:encoded><![CDATA[<p>Die Verwendung von Einbettungen zur Verbesserung der Relevanz und Genauigkeit der Informationswiedergewinnung hat im Laufe der Jahre deutlich zugenommen. Tools wie Elasticsearch wurden weiterentwickelt, um diese Art von Daten durch spezialisierte Feldtypen wie dichte Vektoren, dünnbesetzte Vektoren und semantischen Text zu unterstützen. Um jedoch gute Ergebnisse zu erzielen, ist es unerlässlich zu verstehen, wie man Embeddings den verfügbaren Elasticsearch-Feldtypen <code>semantic_text</code>, <code>dense_vector</code> und <code>sparse_vector</code> korrekt zuordnet.</p><p>In diesem Artikel werden wir diese Feldtypen, ihre jeweiligen Anwendungsbereiche und ihren Zusammenhang mit Strategien zur Einbettungsgenerierung und -nutzung sowohl bei der Indizierung als auch bei der Abfrage besprechen.</p><h2>Dichter Vektortyp</h2><p>Der Feldtyp <code>dense_vector</code> in Elasticsearch dient zur Speicherung dichter Vektoren, die numerische Darstellungen von Daten wie Text, Bildern und Audio darstellen, wobei nahezu alle Dimensionen relevant sind. Diese Vektoren werden mithilfe von Einbettungsmodellen generiert, die von Plattformen wie OpenAI, Cohere oder Hugging Face bereitgestellt werden, und sind so konzipiert, dass sie die Gesamtsemantik der Daten erfassen, auch wenn diese keine exakten Begriffe mit anderen Dokumenten teilen.</p><p>In Elasticsearch können dichte Vektoren je nach verwendetem Modell bis zu 4096 Dimensionen haben. Das Modell all-MiniLM-L6-v2 erzeugt beispielsweise Vektoren mit 384 Dimensionen, während das Modell text-embedding-ada-002 von OpenAI Vektoren mit 1536 Dimensionen erzeugt.</p><p>Das Feld <code>dense_vector</code> wird üblicherweise als Standardtyp für die Speicherung dieser Art von Einbettungen verwendet, wenn eine größere Kontrolle erforderlich ist, z. B. durch die Verwendung vorab generierter Vektoren, die Anwendung benutzerdefinierter Ähnlichkeitsfunktionen oder die Integration mit externen Modellen.</p><h3>Wann und warum sollte man dense_vector-Typ verwenden?</h3><p>Dichte Vektoren eignen sich hervorragend, um semantische Ähnlichkeiten zwischen Sätzen, Absätzen oder ganzen Dokumenten zu erfassen. Sie eignen sich hervorragend, wenn es darum geht, die Gesamtbedeutung von Texten zu vergleichen, selbst wenn diese nicht dieselben Begriffe verwenden.</p><p>Das dichte Vektorfeld ist ideal, wenn Sie bereits eine externe Embedding-Generierungspipeline mit Modellen von Plattformen wie OpenAI, Cohere oder Hugging Face verwenden und diese Vektoren nur manuell speichern und abfragen möchten. Dieser Feldtyp bietet eine hohe Kompatibilität mit Einbettungsmodellen und volle Flexibilität bei der Generierung und Abfrage, sodass Sie steuern können, wie die Vektoren erzeugt, indiziert und während der Suche verwendet werden.</p><p>Darüber hinaus unterstützt es verschiedene Formen der semantischen Suche, mit Abfragen wie k-NN oder script_score für Fälle, in denen es notwendig ist, die Ranking-Logik anzupassen. Diese Möglichkeiten machen den dichten Vektor ideal für Anwendungen wie RAG (Retrieval-Augmented Generation), Empfehlungssysteme und personalisierte Suchen auf der Grundlage von Ähnlichkeit.</p><p>Schließlich ermöglicht Ihnen das Feld, die Relevanzlogik anzupassen, indem Sie Funktionen wie <code>cosineSimilarity</code>, <code>dotProduct</code> oder <code>l2norm</code> verwenden, um das Ranking an die Bedürfnisse Ihres Anwendungsfalls anzupassen. </p><p>Dichte Vektoren bleiben die beste Option für diejenigen, die Flexibilität, Anpassungsmöglichkeiten und Kompatibilität mit fortgeschrittenen Anwendungsfällen wie den oben genannten benötigen.</p><h3>Wie verwendet man die Abfrage für den Datentyp „dichter Vektor“?</h3><p>Bei Suchen in Feldern, die als <strong><code>dense_vector</code></strong> definiert sind, wird die k-nächste-Nachbarn-Abfrage verwendet. Diese Abfrage dient dazu, Dokumente zu finden, deren Dichtevektor dem Abfragevektor am nächsten kommt. Nachfolgend ein Beispiel für die Anwendung einer k-NN-Abfrage auf ein dichtes Vektorfeld:</p>{
  "knn": {
    "field": "my_dense_vector",
    "k": 10,
    "num_candidates": 50,
    "query_vector": [/* vector generated by model */]
  }
}<p>Zusätzlich zur k-NN-Abfrage besteht die Möglichkeit, bei Bedarf die Dokumentenbewertung anzupassen, indem man die script_score-Abfrage verwendet und sie mit Vektorvergleichsfunktionen wie <strong>cosineSimilarity, dotProduct oder l2norm</strong> kombiniert, um die Relevanz kontrollierter zu berechnen. Siehe das Beispiel:</p>{
"script_score": {
    "query": { "match_all": {} },
    "script": {
      "source": "cosineSimilarity(params.query_vector,
'my_dense_vector') + 1.0",
      "params": {
        "query_vector": [/* vector */]
      }
    }
  }
}<p>Wer tiefer in die Materie einsteigen möchte, dem empfehle ich den Artikel <a href="https://www.elastic.co/search-labs/blog/vector-search-set-up-elasticsearch">„Wie man die Vektorsuche in Elasticsearch einrichtet“.</a></p><p></p><h2>Sparse Vektortyp</h2><p>Der Feldtyp <strong><code>sparse_vector</code></strong> dient zum Speichern von dünnbesetzten Vektoren. Dabei handelt es sich um numerische Darstellungen, bei denen die meisten Werte null sind und nur wenige Terme ein signifikantes Gewicht haben. Dieser Vektortyp ist in termbasierten Modellen wie SPLADE oder ELSER (Elastic Learned Sparse EncodeR) üblich.</p><h3>Wann und warum sollte man den Sparse-Vektor-Typ verwenden?</h3><p>Sparse Vektoren sind ideal, wenn Sie eine präzisere Suche in lexikalischen Begriffen benötigen, ohne dabei semantische Intelligenz einzubüßen. Sie stellen den Text als Token/Wert-Paare dar und heben nur die relevantesten Begriffe mit zugehörigen Gewichtungen hervor, was für Klarheit, Kontrolle und Effizienz sorgt.</p><p>Dieser Feldtyp ist besonders nützlich, wenn Sie Vektoren auf der Grundlage von Begriffen generieren, wie beispielsweise in den Modellen ELSER oder SPLADE, die jedem Token unterschiedliche Gewichte zuweisen, basierend auf seiner relativen Bedeutung im Text.</p><p>Für den Fall, dass Sie den Einfluss bestimmter Wörter in der Suchanfrage steuern möchten, ermöglichen Ihnen Sparse-Vektor-Typen, die Gewichtung der Begriffe manuell anzupassen, um die Rangfolge der Ergebnisse zu optimieren.</p><p>Zu den wichtigsten Vorteilen zählen die Transparenz bei der Suche, da klar ersichtlich ist, warum ein Dokument als relevant eingestuft wurde, und die Speichereffizienz, da nur Token mit einem Wert ungleich Null gespeichert werden, im Gegensatz zu dichten Vektoren, die alle Dimensionen speichern.</p><p>Darüber hinaus sind dünnbesetzte Vektoren die ideale Ergänzung in hybriden Suchstrategien und können sogar mit dichtbesetzten Vektoren kombiniert werden, um lexikalische Präzision mit semantischem Verständnis zu verbinden.</p><h3>Wie verwendet man die Abfrage für den Datentyp „dünnbesetzter Vektor“?</h3><p>Mit der <strong><code>sparse_vector</code></strong> -Abfrage können Sie nach Dokumenten auf Basis eines Abfragevektors im Token/Wert-Format suchen. Nachfolgend finden Sie ein Beispiel für die Abfrage:</p>{
  "query": {
    "sparse_vector": {
      "field": "field_sparse",
      "query_vector": {
        "token1": 0.6,
        "token2": 0.2,
        "token3": 0.9
      }
    }
  }
}<p>Falls Sie ein trainiertes Modell bevorzugen, können Sie einen Inferenzendpunkt verwenden, der den Abfragetext automatisch in einen Sparse-Vektor umwandelt:</p>{
  "query": {
    "sparse_vector": {
      "field": "field_sparse",
      "inference_id": "the inference ID to produce the token/weights",
      "query": "search text"
    }
  }
}<p>Um dieses Thema weiter zu vertiefen, empfehle ich die Lektüre von <a href="https://www.elastic.co/search-labs/blog/sparse-vector-embedding">„Understanding sparse vector embeddings with trained ML models“</a>.</p><h2>Semantischer Texttyp</h2><p>Der Feldtyp <strong><code>semantic_text</code></strong> ist die einfachste und unkomplizierteste Möglichkeit, die semantische Suche in Elasticsearch zu nutzen. Die Generierung von Einbettungen erfolgt automatisch sowohl zur Indexierungs- als auch zur Abfragezeit über einen Inferenz-Endpunkt. Das bedeutet, dass Sie sich keine Gedanken über das manuelle Generieren oder Speichern von Vektoren machen müssen.</p><h3>Wann und warum sollte man semantischen Text verwenden?</h3><p>Das Feld <code>semantic_text</code> ist ideal für diejenigen, die mit minimalem technischem Aufwand und ohne manuelle Vektorbearbeitung beginnen möchten. Dieses Feld automatisiert Schritte wie die Generierung von Einbettungen und die Vektorsuche, wodurch die Einrichtung schneller und bequemer wird.</p><p>Sie sollten die Verwendung <code>semantic_text</code> in Betracht ziehen, wenn Sie Wert auf <strong>Einfachheit und Abstraktion</strong> legen, da dadurch <strong>die Komplexität der manuellen Konfiguration von Mappings, Embedding-Generierung und Ingestion-Pipelines entfällt</strong>. Wählen Sie einfach das Inferenzmodell aus, und Elasticsearch kümmert sich um den Rest.</p><p>Zu den wichtigsten Vorteilen gehören <strong>die automatische Generierung von Einbettungen,</strong> die sowohl während der Indizierung als auch während der Abfrage erfolgt, und <strong>das sofort einsatzbereite Mapping</strong>, das vorkonfiguriert ist, um das ausgewählte Inferenzmodell zu unterstützen.</p><p>Darüber hinaus bietet das Feld <strong>native Unterstützung für die automatische Aufteilung langer Texte (Text Chunking)</strong>, wodurch große Texte in kleinere Abschnitte unterteilt werden können, von denen jeder seine eigene Einbettung hat, was die Suchgenauigkeit verbessert. Dies steigert die Produktivität enorm, insbesondere für Teams, die schnell Mehrwert liefern wollen, ohne sich mit der zugrundeliegenden Technik der semantischen Suche auseinandersetzen zu müssen.</p><p>Allerdings bietet <code>semantic_text</code> zwar Geschwindigkeit und Einfachheit, hat aber auch einige Einschränkungen. Es ermöglicht die Verwendung marktüblicher Modelle, sofern diese als Inferenzendpunkte in Elasticsearch verfügbar sind. <strong>Es unterstützt jedoch keine extern generierten Einbettungen</strong>, wie es mit dem Feld <code>dense_vector</code> möglich ist.</p><p>Wenn Sie mehr Kontrolle darüber benötigen, wie Vektoren generiert werden, Ihre eigenen Einbettungen verwenden möchten oder mehrere Felder für fortgeschrittene Strategien kombinieren müssen, bieten die Felder <code>dense_vector</code> und <code>sparse_vector</code> die Flexibilität, die für individuellere oder domänenspezifische Szenarien erforderlich ist.</p><h3>Wie man die Abfrage für semantischen Texttyp verwendet</h3><p>Vor <strong><code>semantic_text</code></strong> war es notwendig, je nach Art der Einbettung (dicht oder dünn) eine andere Abfrage zu verwenden. Für dünn besetzte Felder wurde eine <code>sparse_vector</code> -Abfrage verwendet, während für <code>dense_vector</code> -Felder KNN-Abfragen erforderlich waren.</p><p>Bei der semantischen Textsuche wird die Suche mithilfe der <a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-semantic-query">semantischen Abfrage</a> durchgeführt, die automatisch den Abfragevektor generiert und ihn mit den Einbettungen der indizierten Dokumente vergleicht. Mit dem Typ <strong><code>semantic_text</code></strong> können Sie einen Inferenzendpunkt definieren, um die Abfrage einzubetten. Wenn jedoch kein Endpunkt angegeben wird, wird derselbe Endpunkt, der während der Indizierung verwendet wurde, auf die Abfrage angewendet.</p>{
  "query": {
    "semantic": {
      "field": "semantic_text_field",
      "query": "search text"
    }
  }
}<p>Um mehr zu erfahren, empfehle ich die Lektüre des Artikels <a href="https://www.elastic.co/search-labs/blog/semantic-search-simplified-semantic-text">Elasticsearch new semantic_text mapping: Simplifying semantic search</a>.</p><h2>Fazit</h2><p>Bei der Auswahl der Methode zum Mapping von Embeddings in Elasticsearch ist es wichtig zu verstehen, wie Sie die Vektoren generieren möchten und welchen Grad an Kontrolle Sie darüber benötigen. Wenn Sie Wert auf Einfachheit legen, ermöglicht das semantische Textfeld eine automatische und skalierbare semantische Suche und ist damit ideal für viele erste Anwendungsfälle. Wenn mehr Kontrolle, feinabgestimmte Leistung oder die Integration mit benutzerdefinierten Modellen erforderlich ist, bieten die dichten Vektorfelder und die dünnbesetzten Vektorfelder die notwendige Flexibilität.</p><p>Der ideale Feldtyp hängt von Ihrem Anwendungsfall, der verfügbaren Infrastruktur und dem Reifegrad Ihres Machine-Learning-Stacks ab. Am wichtigsten ist jedoch, dass Elastic die Werkzeuge bietet, um moderne und hochgradig anpassungsfähige Suchsysteme zu entwickeln.</p><h2>Referenzen</h2><ul><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html">Semantischer Textfeldtyp</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/sparse-vector.html">Sparse Vektorfeldtyp</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html">Dichtes Vektorfeld</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-semantic-query.html">Semantische Anfrage</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-sparse-vector-query.html">Sparse Vektorabfrage</a></p></li><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html">kNN-Suche</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/semantic-search-simplified-semantic-text">Elasticsearch: Neues semantisches Textmapping: Vereinfachung der semantischen Suche</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/sparse-vector-embedding">Verständnis von spärlichen Vektoreinbettungen mit trainierten ML-Modellen</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/mapping-embeddings-to-elasticsearch-field-types</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/mapping-embeddings-to-elasticsearch-field-types</guid>
    <category><![CDATA[Vektordatenbank]]></category>
    <category><![CDATA[Mappings]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72cd3c2601b22886/6a17083b0c4857259901a9dc/f98fdff837db55b466780c0bae672aa6f6c3a966-1200x628.png" length="0" type="image/png"/>
    <pubDate>Tue, 13 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Generierung von Filtern und Facetten mithilfe von maschinellem Lernen]]></title>
    <description><![CDATA[Untersuchung der Vor- und Nachteile der Automatisierung der Erstellung von Filtern und Facetten in einer Suchanwendung mithilfe von ML-Modellen im Vergleich zum klassischen, fest codierten Ansatz.]]></description>
    <content:encoded><![CDATA[<p>Filter und Facetten sind Mechanismen, die dazu dienen, Suchergebnisse zu verfeinern und Nutzern zu helfen, relevante Inhalte oder Produkte schneller zu finden. Beim klassischen Ansatz werden die Regeln manuell definiert. In einem Filmkatalog sind beispielsweise Attribute wie das Genre vordefiniert und können in Filtern und Facetten verwendet werden. Andererseits können mit KI-Modellen automatisch neue Attribute aus den Eigenschaften von Filmen extrahiert werden, wodurch der Prozess dynamischer und personalisierter wird. In diesem Blog untersuchen wir die Vor- und Nachteile jeder Methode und beleuchten deren Anwendungsbereiche und Herausforderungen.</p><h2>Filter und Facetten im Vergleich</h2><p>Bevor wir beginnen, definieren wir zunächst, was Filter und Facetten sind. <strong>Filter</strong> sind vordefinierte Attribute, die verwendet werden, um eine Reihe von Ergebnissen einzuschränken. Auf einem Marktplatz stehen beispielsweise Filter schon vor der eigentlichen Suche zur Verfügung. Der Benutzer kann vor der Suche nach <strong>„PS5“</strong> eine Kategorie auswählen, zum Beispiel <strong>„Videospiele“</strong>, und so die Suche auf eine spezifischere Teilmenge anstatt der gesamten Datenbank eingrenzen. Dadurch erhöhen sich die Chancen auf relevantere Ergebnisse erheblich.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0a77b38aae238938/6a170b821949f72a52e7aa51/5ed8868fa5017d034e1273e35c884a5430afdf3c-1600x937.png" alt="Filter" /><p><strong>Facetten</strong> funktionieren ähnlich wie Filter, sind aber erst nach der Durchführung der Suche verfügbar. Mit anderen Worten: Die Suche liefert Ergebnisse, und auf deren Grundlage wird eine neue Liste von Verfeinerungsoptionen generiert. Bei der Suche nach einer PS5-Konsole werden beispielsweise Aspekte wie <strong>Speicherkapazität</strong>, <strong>Versandkosten</strong> und <strong>Farbe</strong> angezeigt, um den Nutzern bei der Auswahl des idealen Produkts zu helfen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt166e356b80d423ef/6a170b840e2e494ca341a10f/c5633fcc5b6fbb916110faf32144d8d43572e33a-1600x937.png" alt="Facetten " /><p>Nachdem wir nun Filter und Facetten definiert haben, wollen wir die Auswirkungen der klassischen und der auf maschinellem Lernen (ML) basierenden Ansätze auf ihre Implementierung und Verwendung erörtern. Jede Methode hat Vor- und Nachteile, die die Effizienz der Suche beeinflussen.</p><h2>Klassischer Ansatz für Filter und Facetten</h2><p>Bei diesem Ansatz werden Filter und Facetten manuell anhand vordefinierter Regeln definiert. Dies bedeutet, dass die zur Verfeinerung der Suche verfügbaren Attribute festgelegt und im Voraus geplant sind, wobei die Katalogstruktur und die Bedürfnisse der Nutzer berücksichtigt werden.</p><p>Auf einem Marktplatz können beispielsweise Kategorien wie „Elektronik“ oder „Mode“ über spezifische Filter wie Marke, Format und Preisspanne verfügen. Diese Regeln werden statisch erstellt, um eine einheitliche Sucherfahrung zu gewährleisten, erfordern jedoch manuelle Anpassungen, sobald neue Produkte oder Kategorien auftauchen.</p><p>Obwohl dieser Ansatz Vorhersagbarkeit und Kontrolle über die angezeigten Filter und Facetten bietet, kann er an seine Grenzen stoßen, wenn neue Trends entstehen, die eine dynamische Anpassung erfordern.</p><p><strong>Vorteile:</strong></p><ul><li><p><strong>Vorhersagbarkeit und Kontrolle:</strong> Da Filter und Facetten manuell definiert werden, wird die Verwaltung einfacher.</p></li><li><p><strong>Geringe Komplexität:</strong> Es müssen keine Modelle trainiert werden.</p></li><li><p><strong>Wartungsfreundlichkeit:</strong> Da die Regeln vordefiniert sind, können Anpassungen und Korrekturen schnell vorgenommen werden.</p></li></ul><p><strong>Nachteile</strong>:</p><ul><li><p><strong>Neuindizierung für neue Filter erforderlich:</strong> Wenn ein neues Attribut als Filter verwendet werden soll, muss der gesamte Datensatz neu indiziert werden, um sicherzustellen, dass die Dokumente diese Information enthalten.</p></li><li><p><strong>Fehlende dynamische Anpassung:</strong> Filter sind statisch und passen sich nicht automatisch an Änderungen im Nutzerverhalten an.</p></li></ul><h3>Implementierung von Filtern/Facetten – Klassischer Ansatz</h3><p>In <strong>Dev Tools, Kibana</strong>, werden wir eine Demonstration von Filtern/Facetten mit dem <strong>klassischen Ansatz</strong> erstellen.</p><p>Zuerst definieren wir die Zuordnung zur Strukturierung des Index:</p>PUT videogames
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "brand": { "type": "keyword" },
      "storage": { "type": "keyword" },
      "price": { "type": "float" },
      "description": { "type": "text" }
    }
  }
}<p>Die Felder <strong>„Marke“</strong> und <strong>„Speicherort</strong> “ sind als <strong>Schlüsselwort</strong> festgelegt, sodass sie direkt in Aggregationen (<strong>Facetten</strong>) verwendet werden können. Das <strong>Preisfeld</strong> ist vom Typ <strong>Float</strong>, wodurch die Erstellung von <strong>Preisspannen</strong> ermöglicht wird.</p><p>Im nächsten Schritt werden die Produktdaten indexiert:</p>POST videogames/_bulk
{ "index": { "_id": 1 } }
{ "name": "Play Station 5", "brand": "Sony", "storage": "1TB", "price": 499.99, "description": "Stunning Gaming: Marvel at stunning graphics and experience the features of the new PS5. Breathtaking Immersion: Discover a deeper gaming experience with support for haptic feedback, adaptive triggers, and 3D Audio technology. Slim Design: With the PS5 Digital Edition, gamers get powerful gaming technology in a sleek, compact design. 1TB of Storage: Have your favorite games ready and waiting for you to play with 1TB of built-in SSD storage. Backward Compatibility and Game Boost: The PS5 console can play over 4,000 PS4 games. With Game Boost, you can even enjoy faster, smoother frame rates in some of the best PS4 console games." }
{ "index": { "_id": 2 } }
{ "name": "Xbox Series X", "brand": "Microsoft", "storage": "1TB", "price": 499.99, "description": "Fastest, most powerful Xbox console ever. Play thousands of titles: Every game looks and plays better on Xbox Series X. At the heart of Series X is the Xbox Velocity. Architecture, which combines a custom SSD and built-in software to significantly reduce load times in and out of game. Switch between multiple games in an instant with Quick Resume. Explore new worlds and experience the action like never before with an unparalleled 12 teraflops of graphics processing power. Enjoy 4K gaming at up to 120 frames per second, premium advanced 3D sound, and more. 4K at 120 FPS: requires compatible content and display X version - with disc drive" }
{ "index": { "_id": 3 } }
{ "name": "Nintendo Switch", "brand": "Nintendo", "storage": "512GB", "price": 299.99, "description": "SHARPER, VIBRANT VISUALS. The new 7-inch screen on the Nintendo Switch OLED takes your gaming to the next level: vibrant colors with sharp contrasts for every moment. INTEGRATED GAMEPLAY. Enjoy the console's many multiplayer modes and connect with other players. Online or locally, the fun on the Nintendo Switch is guaranteed. ENJOY IMMERSION FOR LONGER. In addition to delivering an unparalleled experience, thanks to its improved audio, the Nintendo Switch has a rechargeable battery while you play. From 4.5 hours to 9 hours of battery life. INCLUDES SUPER MARIO BROS. WONDER. Transform your world with the phenomenal flowers in this new Mario game, full of amazing adventures, power-ups and new abilities. NINTENDO SWITCH ONLINE SUBSCRIPTION. Access online games, play with friends and enjoy the exclusive benefits of the Nintendo Switch Online subscription." }
{ "index": { "_id": 4 } }
{ "name": "Steam Deck", "brand": "Valve", "storage": "512GB", "price": 399.99, "description": "You can save games, apps, photos and videos without worrying about space. High-Level Performance: The 4-core processor and graphics ensure a dynamic experience and fast responses. High-Definition Images: Smooth transitions and sharp images provide complete immersion in the game. Wireless Connectivity: Wi-Fi technology allows you to play wherever you want, without wires or cables limiting your fun" }
{ "index": { "_id": 5 } }
{ "name": "Nintendo Switch Lite", "brand": "Nintendo", "storage": "512GB", "price": 299.99, "description": "MADE TO BE PORTABLE. Nintendo Switch Lite is designed specifically for portable gaming. The console lets you jump into your favorite games wherever you are. COMPACT AND LIGHTWEIGHT. With its sleek, lightweight design, this console is ready to hit the road wherever you are. COMPATIBLE GAMES. The Nintendo Switch Lite system plays the library of Nintendo Switch games that work in handheld mode. A WORLD OF COLOR TO CHOOSE FROM. Available in a variety of vibrant and unique colors, Nintendo Switch Lite lets you bring even more personality wherever you go." }<p>Nun wollen wir klassische Aspekte herausfiltern, indem wir die Ergebnisse nach Marke, Speicherort und Preisspanne gruppieren. In der Abfrage wurde Größe:0 definiert. In diesem Szenario besteht das Ziel darin, nur die Aggregationsergebnisse abzurufen, ohne die Dokumente einzubeziehen, die der Abfrage entsprechen.</p>POST videogames/_search
{
  "size": 0,
  "aggs": {
    "brands": {
      "terms": { "field": "brand" }
    },
    "storage_sizes": {
      "terms": { "field": "storage" }
    },
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 300 },   
          { "from": 300, "to": 500 },  
          { "from": 500 }  
        ]
      }
    }
  }
}<p>Die Antwort wird Zählungen für <strong>Marke</strong>, <strong>Lager</strong> und <strong>Preis</strong> enthalten und so zur Erstellung von Filtern und Facetten beitragen.</p>"aggregations": {
   "brands": {
     "doc_count_error_upper_bound": 0,
     "sum_other_doc_count": 0,
     "buckets": [
       {
         "key": "Microsoft",
         "doc_count": 1
       },
       {
         "key": "Nintendo",
         "doc_count": 1
       },
       {
         "key": "Sony",
         "doc_count": 1
       },
       {
         "key": "Valve",
         "doc_count": 1
       }
     ]
   },
   "storage_sizes": {
     "doc_count_error_upper_bound": 0,
     "sum_other_doc_count": 0,
     "buckets": [
       {
         "key": "1TB",
         "doc_count": 2
       },
       {
         "key": "512GB",
         "doc_count": 2
       }
     ]
   },
   "price_ranges": {
     "buckets": [
       {
         "key": "*-300.0",
         "to": 300,
         "doc_count": 1
       },
       {
         "key": "300.0-500.0",
         "from": 300,
         "to": 500,
         "doc_count": 3
       },
       {
         "key": "500.0-*",
         "from": 500,
         "doc_count": 0
       }
     ]
   }
 }<h2>Ansatz, der auf Machine Learning/KI basiert, für Filter und Facetten</h2><p>Bei diesem Ansatz analysieren Modelle des maschinellen Lernens (ML), einschließlich Techniken der künstlichen Intelligenz (KI), Datenattribute, um relevante Filter und Facetten zu generieren. Anstatt sich auf vordefinierte Regeln zu stützen, nutzt ML/KI die Merkmale indexierter Daten. Dies ermöglicht die dynamische Entdeckung neuer Facetten und Filter.</p><p><strong>Vorteile</strong>:</p><ul><li><p><strong>Automatische Aktualisierungen:</strong> Neue Filter und Facetten werden automatisch generiert, ohne dass manuelle Anpassungen erforderlich sind.</p></li><li><p><strong>Entdeckung neuer Attribute:</strong> Es kann <strong>bisher unberücksichtigte </strong>Datenmerkmale als Filter identifizieren und so das Sucherlebnis bereichern.</p></li><li><p><strong>Reduzierter manueller Aufwand:</strong> Das Team muss keine Filterregeln mehr ständig definieren und aktualisieren, da die KI aus den verfügbaren Daten lernt.</p></li></ul><p><strong>Nachteile:</strong></p><ul><li><p><strong>Wartungsaufwand:</strong> Die Verwendung von Modellen kann eine Vorvalidierung erfordern, um die Konsistenz der generierten Filter sicherzustellen.</p></li><li><p><strong>Erfordert Expertise in den Bereichen Maschinelles Lernen und Künstliche Intelligenz:</strong> Die Lösung erfordert qualifizierte Fachkräfte, die die Modellleistung feinabstimmen und überwachen.</p></li><li><p><strong>Risiko irrelevanter Filter:</strong> Wenn das Modell nicht gut kalibriert ist, kann es Facetten generieren, die für die Benutzer nicht nützlich sind.</p></li><li><p><strong>Kosten:</strong> Der Einsatz von ML und KI kann die Inanspruchnahme von Dienstleistungen Dritter erfordern, was die Betriebskosten erhöht.</p></li></ul><p>Es ist wichtig zu beachten, dass selbst bei einem gut kalibrierten Modell und einer gut formulierten Eingabeaufforderung die generierten Facetten noch einen Überprüfungsschritt durchlaufen sollten. Diese Validierung kann manuell oder auf der Grundlage von Moderationsregeln erfolgen, um sicherzustellen, dass die Inhalte angemessen und sicher sind. Dies ist zwar nicht unbedingt ein Nachteil, aber dennoch ein wichtiger Aspekt, um die Qualität und Eignung der Facetten sicherzustellen, bevor sie den Nutzern zur Verfügung gestellt werden.</p><h3>Implementierung von Filtern/Facetten – KI-Ansatz</h3><p>In dieser Demonstration verwenden wir ein KI-Modell, um Produkteigenschaften automatisch zu analysieren und relevante Attribute vorzuschlagen. Mithilfe einer gut strukturierten Eingabeaufforderung extrahieren wir Informationen aus dem Katalog und wandeln diese in Filter und Facetten um. Im Folgenden stellen wir jeden einzelnen Schritt des Prozesses vor.</p><p>Zunächst werden wir die <strong>Inference API</strong> verwenden, um einen Endpunkt für die Integration mit einem ML-Dienst zu registrieren. Nachfolgend ein Beispiel für die Integration mit <strong>dem Dienst von OpenAI</strong>.</p>PUT _inference/completion/generate_filter_ia
{
   "service": "openai",
   "service_settings": {
       "api_key": "your-key",
       "model_id": "gpt-4o-mini"
   }
}<p>Nun definieren wir die Pipeline, um die Eingabeaufforderung auszuführen und die vom Modell generierten neuen Filter zu erhalten.</p>PUT /_ingest/pipeline/generate_filter_ai
{
   "processors": [
     {
       "script": {
         "source": """ctx.prompt = "You are an expert in data organization for search and product categorization. Your task is to analyze the following product and identify the best dynamic facets that can be used in an e-commerce search experience. Product: " + ctx.name + "description: " + ctx.description + "Instructions: - Analyze the product name and description. - Extract only the dynamic facets (technological features or product characteristics that can be inferred from the description, try to create max 3 facets by characteristics found). Put the values into an array. Using key and value, e.g. dynamic_facets: [{ \"name\": \"Gaming Experience\", \"value\": \"Haptic Feedback\" },{ \"name\": \"Gaming Experience\", \"value\": \"Adaptive Triggers\" } - Return only a JSON."
         """
       }
     },
     {
       "inference": {
         "model_id": "generate_filter_ia",
         "input_output": {
           "input_field": "prompt",
           "output_field": "result"
         }
       }
     },
     {
       "gsub": {
         "field": "result",
         "pattern": "```json",
         "replacement": ""
       }
     },
     {
       "json" : {
         "field" : "result",
         "strict_json_parsing": false,
         "add_to_root" : true
       }
     },
     {
       "remove": {
         "field": "result"
       }
     },
     {
       "remove": {
         "field": "prompt"
       }
     }
   ]
}<p>Eine Simulation dieser Pipeline für das Produkt „PlayStation 5“ wird mit folgender Beschreibung durchgeführt:</p><p><em>Atemberaubendes Spielerlebnis: Bestaunen Sie die beeindruckende Grafik und erleben Sie die Funktionen der neuen PS5.</em></p><p><em>Atemberaubendes Eintauchen: Entdecken Sie ein intensiveres Spielerlebnis mit Unterstützung für haptisches Feedback, adaptive Trigger und 3D-Audiotechnologie.</em></p><p><em>Schlankes Design: Mit der PS5 Digital Edition erhalten Gamer leistungsstarke Gaming-Technologie in einem schlanken, kompakten Design.</em></p><p><em>1 TB Speicherplatz: Dank 1 TB integriertem SSD-Speicher sind Ihre Lieblingsspiele immer griffbereit und warten nur darauf, von Ihnen gespielt zu werden.</em></p><p><em>Abwärtskompatibilität und Game Boost: Die PS5-Konsole kann über 4.000 PS4-Spiele abspielen. Mit Game Boost können Sie sogar in einigen der besten PS4-Konsolenspiele schnellere und flüssigere Bildwiederholraten genießen.</em></p><p>Betrachten wir nun die von dieser Simulation generierte Prompt-Ausgabe.</p>{
 "docs": [
   {
     "doc": {
       "_index": "index",
       "_version": "-3",
       "_id": "1",
       "_source": {
         "name": "Play Station 5",
         "result": """```json
{
 "dynamic_facets": [
   { "name": "Storage Capacity", "value": "1TB SSD" },
   { "name": "Graphics Technology", "value": "Stunning Graphics" },
   { "name": "Audio Technology", "value": "3D Audio" }
 ]
}
```""",
         "description": "Stunning Gaming: Marvel at stunning graphics and experience the features of the new PS5. Breathtaking Immersion: Discover a deeper gaming experience with support for haptic feedback, adaptive triggers, and 3D Audio technology. Slim Design: With the PS5 Digital Edition, gamers get powerful gaming technology in a sleek, compact design. 1TB of Storage: Have your favorite games ready and waiting for you to play with 1TB of built-in SSD storage. Backward Compatibility and Game Boost: The PS5 console can play over 4,000 PS4 games. With Game Boost, you can even enjoy faster, smoother frame rates in some of the best PS4 console games.",
         "model_id": "generate_filter_ia",
         "prompt": """You are an expert in data organization for search and product categorization. Your task is to analyze the following product and identify the best dynamic facets that can be used in an e-commerce search experience. Product: Play Station 5description: Stunning Gaming: Marvel at stunning graphics and experience the features of the new PS5. Breathtaking Immersion: Discover a deeper gaming experience with support for haptic feedback, adaptive triggers, and 3D Audio technology. Slim Design: With the PS5 Digital Edition, gamers get powerful gaming technology in a sleek, compact design. 1TB of Storage: Have your favorite games ready and waiting for you to play with 1TB of built-in SSD storage. Backward Compatibility and Game Boost: The PS5 console can play over 4,000 PS4 games. With Game Boost, you can even enjoy faster, smoother frame rates in some of the best PS4 console games.Instructions: - Analyze the product name and description. - Extract only the dynamic facets (technological features or product characteristics that can be inferred from the description, try create max 3 facets by characteristics found). Put the values like arrays. Using key and value, e.g. dynamic_facets: [{ "name": "Gaming Experience", "value": "Haptic Feedback" },{ "name": "Gaming Experience", "value": "Adaptive Triggers" } - Return only a JSON."""
       },
       "_ingest": {
         "timestamp": "2025-03-19T22:14:32.0161803Z"
       }
     }
   }
 ]
}<p>Nun wird dem neuen Index ein neues Feld, <strong>dynamic_facets</strong>, hinzugefügt, um die von der KI generierten Facetten zu speichern.</p>PUT videogames_1
{
 "mappings": {
   "properties": {
     "name": { "type": "text" },
     "brand": { "type": "keyword" },
     "storage": { "type": "keyword" },
     "price": { "type": "float" },
     "description": { "type": "text" },
     "dynamic_facets": { "type": "nested",
     "properties": { "name": { "type": "keyword" },
                     "value": { "type": "keyword" } } }
   }
 }
}<p>Mithilfe der <strong>Reindex API</strong> werden wir den <strong>Videospiele-</strong> Index auf <strong>videogames_1</strong> neu indizieren und dabei die <strong>generate_filter_ai-</strong> Pipeline anwenden. Diese Pipeline generiert während der Indizierung automatisch dynamische Facetten.</p>POST _reindex?wait_for_completion=false
{
 "source": {
   "index": "videogames"
 },
 "dest": {
   "index": "videogames_1",
   "pipeline": "generate_filter_ai"
 }
}<p>Nun führen wir eine Suche durch und rufen die neuen Filter ab:</p>GET videogames_1/_search
{
 "size": 0,
 "query": {
   "match": {
     "name": "nintendo"
   }
 },
 "aggs": {
   "dynamic_facets": {
     "nested": {
       "path": "dynamic_facets"
     },
     "aggs": {
       "facets": {
         "terms": {
           "field": "dynamic_facets.name"
         },
         "aggs": {
           "facets": {
             "terms": {
               "field": "dynamic_facets.value"
             }
           }
         }
       }
     }
   }
 }
}<p>Ergebnisse:</p>"aggregations": {
   "dynamic_facets": {
     "doc_count": 3,
     "facets": {
       "doc_count_error_upper_bound": 0,
       "sum_other_doc_count": 0,
       "buckets": [
         {
           "key": "Frame Rate",
           "doc_count": 1,
           "facets": {
             "doc_count_error_upper_bound": 0,
             "sum_other_doc_count": 0,
             "buckets": [
               {
                 "key": "120 FPS",
                 "doc_count": 1
               }
             ]
           }
         },
         {
           "key": "Gaming Resolution",
           "doc_count": 1,
           "facets": {
             "doc_count_error_upper_bound": 0,
             "sum_other_doc_count": 0,
             "buckets": [
               {
                 "key": "4K",
                 "doc_count": 1
               }
             ]
           }
         },
         {
           "key": "Graphics Processing Power",
           "doc_count": 1,
           "facets": {
             "doc_count_error_upper_bound": 0,
             "sum_other_doc_count": 0,
             "buckets": [
               {
                 "key": "12 Teraflops",
                 "doc_count": 1
               }
             ]
           }
         }
       ]
     }
   }
 }<p>Zur Veranschaulichung der Umsetzung der einzelnen Aspekte folgt unten ein einfaches Frontend:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb0d6aa40caf7a91a/6a170b86ab7f0839afdb9eb6/12b6d9d4f4d0985848d92841545fd22b7253ae6d-1600x1288.png" alt="Umsetzung der Aspekte" /><p>Der hier dargestellte UI-Code befindet sich <a href="https://gist.github.com/andreluiz1987/06d9ec1b381e942e9def0e969bd811a0">hier</a>.</p><h2>Fazit</h2><p>Beide Ansätze zur Erstellung von Filtern und Facetten haben ihre Vor- und Nachteile. Der klassische Ansatz, der auf manuellen Regeln basiert, bietet Kontrolle und niedrigere Kosten, erfordert jedoch ständige Aktualisierungen und passt sich nicht dynamisch an neue Produkte oder Funktionen an.</p><p>Andererseits automatisiert der auf KI und maschinellem Lernen basierende Ansatz die Facettenextraktion, wodurch die Suche flexibler wird und die Entdeckung neuer Attribute ohne manuelles Eingreifen ermöglicht wird. Allerdings kann dieser Ansatz in der Umsetzung und Aufrechterhaltung komplexer sein und erfordert eine Kalibrierung, um konsistente Ergebnisse zu gewährleisten.</p><p>Die Wahl zwischen klassischen und KI-basierten Ansätzen hängt von den Bedürfnissen und der Komplexität des Unternehmens ab. Bei einfacheren Szenarien, in denen die Datenattribute stabil und vorhersehbar sind, kann der klassische Ansatz effizienter und einfacher zu warten sein, wodurch unnötige Kosten für Infrastruktur und KI-Modelle vermieden werden. Andererseits kann der Einsatz von ML/KI zur Extraktion von Facetten einen erheblichen Mehrwert bieten, das Sucherlebnis verbessern und die Filterung intelligenter gestalten.</p><p>Wichtig ist es zu beurteilen, ob die Automatisierung die Investition rechtfertigt oder ob eine traditionellere Lösung die Geschäftsanforderungen bereits effektiv erfüllt.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/filters-facets-using-ml</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/filters-facets-using-ml</guid>
    <category><![CDATA[Relevanz]]></category>
    <category><![CDATA[ML-Forschung]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4084864dcdaa25d3/6a170b880c485781f901aaa9/6f196643d573614fe5124705c7e4db9bfce004b0-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 03 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Verwendung von Amazon Nova-Modellen in Elasticsearch]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie Amazon Nova-Modelle in Elasticsearch verwenden können, um Sentiment, Authentizität, Zusammenfassungen und Schlüsselwörter automatisch aus Produktbewertungen in Elasticsearch zu extrahieren.]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel werden wir Amazons KI-Modellfamilie Amazon Nova besprechen und lernen, wie man sie zusammen mit Elasticsearch verwendet.</p><h2>Über Amazon Nova</h2><p>Amazon Nova ist eine Familie von künstlichen Intelligenzmodellen von Amazon, die auf Amazon Bedrock verfügbar sind und auf hohe Leistung und Kosteneffizienz ausgelegt sind. Diese Modelle arbeiten mit Text-, Bild- und Videoeingaben, erzeugen Textausgaben und sind für unterschiedliche Anforderungen an Genauigkeit, Geschwindigkeit und Kosten optimiert.</p><h3>Amazon Nova Hauptmodelle</h3><ul><li><p>Amazon Nova Micro: Dieses Modell konzentriert sich ausschließlich auf Textverarbeitung und ist schnell und kostengünstig. Es eignet sich ideal für Übersetzungen, logisches Schlussfolgern, Codevervollständigung und die Lösung mathematischer Probleme. Mit einer Generierungsrate von über 200 Token pro Sekunde eignet es sich ideal für Anwendungen, die sofortige Reaktionen erfordern.</p></li><li><p>Amazon Nova Lite: Ein kostengünstiges multimodales Modell, das Bilder, Videos und Text schnell verarbeiten kann. Es zeichnet sich durch seine Schnelligkeit und Genauigkeit aus und ist für interaktive und hochvolumige Anwendungen geeignet, bei denen Kosten ein wichtiger Faktor sind.</p></li><li><p>Amazon Nova Pro: Die fortschrittlichste Option, die hohe Genauigkeit, Geschwindigkeit und Kosteneffizienz vereint. Ideal für komplexe Aufgaben wie Videozusammenfassung, Frage-Antwort-Systeme, Softwareentwicklung und KI-Agenten. Expertenrezensionen bestätigen seine hervorragende Text- und Bildverarbeitungsfähigkeit sowie seine Fähigkeit, Anweisungen zu befolgen und automatisierte Arbeitsabläufe auszuführen.</p></li></ul><p>Die Amazon Nova-Modelle eignen sich für eine Vielzahl von Anwendungen, von der Content-Erstellung und Datenanalyse bis hin zur Softwareentwicklung und KI-gestützten Prozessautomatisierung.</p><p>Im Folgenden zeigen wir Ihnen, wie Sie Amazon Nova-Modelle in Verbindung mit Elasticsearch für die automatisierte Analyse von Produktbewertungen verwenden können.</p><p>Was wir tun werden:</p><ol><li><p>Erstellen Sie einen Endpunkt über die Inference API, der Amazon Bedrock mit Elasticsearch integriert.</p></li><li><p>Erstellen Sie eine Pipeline mithilfe des Inference Processors, die Aufrufe an den Inference API-Endpunkt durchführt.</p></li><li><p>Indexieren Sie Produktbewertungen und generieren Sie mithilfe der Pipeline automatisch eine Analyse der Bewertungen.</p></li><li><p>Analysieren Sie die Ergebnisse der Integration.</p></li></ol><h2>Erstellung eines Endpoint in der Inference API mit Amazon Nova Lite</h2><p>Zunächst konfigurieren wir die Inference API, um Amazon Bedrock mit Elasticsearch zu integrieren. Wir definieren Amazon Nova Lite, ID <strong>amazon.nova-lite-v1:0</strong>, als das zu verwendende Modell, da es ein ausgewogenes Verhältnis zwischen Geschwindigkeit, Genauigkeit und Kosten bietet.</p><p><strong>Hinweis:</strong> Sie benötigen gültige Zugangsdaten, um Amazon Bedrock nutzen zu können. Die Dokumentation zum Erhalt von Zugriffsschlüsseln finden Sie <a href="https://docs.aws.amazon.com/keyspaces/latest/devguide/create.keypair.html">hier</a>:</p>PUT _inference/completion/bedrock_completion_amazon_nova-lite
{
   "service": "amazonbedrock",
   "service_settings": {
       "access_key": "#access_key#",
       "secret_key": "#secret_key#",
       "region": "us-east-1",
       "provider": "amazontitan",
       "model": "amazon.nova-lite-v1:0"
   }
}<h2>Erstellung der Pipeline für die Bewertungsanalyse</h2><p>Nun erstellen wir eine Verarbeitungspipeline, die den Inferenzprozessor verwendet, um eine Überprüfungsanalyseaufforderung auszuführen. Diese Aufforderung sendet die Bewertungsdaten an Amazon Nova Lite, das Folgendes ausführt:</p><ul><li><p>Sentimentklassifizierung (positiv, negativ oder neutral).</p></li><li><p>Zusammenfassung der Rezension.</p></li><li><p>Schlüsselwortgenerierung.</p></li><li><p>Authentizitätsmessung (authentisch | verdächtig | generisch).</p></li></ul>PUT /_ingest/pipeline/review_analyzer_ai
{
      "processors": [
      {
        "script": 
            {
            "source": """ctx.prompt = "Analyze the following product review and return a structured JSON. Task: - Summarize the review concisely. - Detect and classify the sentiment as positive, neutral, or negative.- Generate relevant tags (keywords) based on the review content and detected sentiment. - Evaluate the authenticity of the review (authentic, suspicious, or generic). Review: " + ctx.review + " Respond in JSON format with the following fields: \"review_analyze\": {\"sentiment\": \"&lt;positive | neutral | negative&gt;\", \"authenticity\": \"&lt;authentic | suspicious | generic&gt;\",\"summary\": \"&lt;short review summary&gt;\", \"keywords\": [\"&lt;keyword 1&gt;\", \"&lt;keyword 2&gt;\", \"...\"]}}}"
            """
            }
      },
      {
        "inference": {
          "model_id": "bedrock_completion_amazon_nova-lite",
          "input_output": {
            "input_field": "prompt",
            "output_field": "result"
          }
        }
      },
      {
        "gsub": {
          "field": "result",
          "pattern": "```json",
          "replacement": ""
        } 
      },
      {
        "json" : {
          "field" : "result",
          "strict_json_parsing": false,
          "add_to_root" : true
        }
      },
      {
        "remove": {
          "field": "result"
        }
      },
      {
        "remove": {
          "field": "prompt"
        }
      }
    ]
}<h2>Indexierungsrezensionen</h2><p>Wir indexieren Produktbewertungen nun mithilfe der Bulk-API. Die zuvor erstellte Pipeline wird automatisch angewendet und fügt die vom Nova-Modell generierte Analyse den indizierten Dokumenten hinzu.</p>POST bulk/
{ "index": { "_index" : "products", "_id": 1, "pipeline":"review_analyzer_ai" } }
{ "product": "Pampers Pants Premium Care Fralda", "review": "Best diaper ever! Great material, lots of cotton, without all that plastic. Doesn't leak! My baby is a boy and every diaper leaked around the waist, this model solved the problem. Even on a small baby it's worth the effort of putting on the short diaper. I put it on my baby at 9 pm and only take it off in the morning, without any leaks." }
{ "index": { "_index" : "products", "_id": 2, "pipeline":"review_analyzer_ai" } }
{ "product": "Portable Electric Body Massager", "review": "It broke in three months for no apparent reason, thank goodness I didn't review it before. I don't recommend buying it because it has a short lifespan." }
{ "index": { "_index" : "products", "_id": 3, "pipeline":"review_analyzer_ai" } }
{ "product": "Havit Fuxi-H3 Black Quad-Mode Wired and Wireless Gaming Headset", "review": "The sound is good for the price, but the connectivity is horrible. You always need to be playing audio, otherwise it loses connection (I work from home, and this is very annoying). Sometimes it loses connection and you have to turn it off and on again to get it back on. The microphone is very sensitive, so it loses connection frequently and you have to turn the headset off and on for the microphone to work again. The flexibility of the stem is useless, because if you move it, the microphone can turn off. Sometimes I need to use Linux and the headset simply doesn't work. It's light and comfortable, the sound is adequate, but the connectivity is terrible." }
{ "index": { "_index" : "products", "_id": 4, "pipeline":"review_analyzer_ai" } }
{ "product": "Air Fryer 4L Oil Free Fryer Mondial", "review": "For those looking for value for money, it's a good option, but the tray (which is underneath the perforated basket) is already peeling a lot. My mother has one just like it and said that hers is even rusting, in other words, the material is MUCH inferior. There's also something that bothers me, because it looks like a microwave, it doesn't fry evenly, it's weaker in the middle and stronger on the sides. Buy at your own risk." }<h2>Abfragen und Analysieren der Ergebnisse</h2><p>Zum Schluss führen wir eine Abfrage durch, um zu sehen, wie das Amazon Nova Lite-Modell die Rezensionen analysiert und klassifiziert. Durch Ausführen von GET products/_search erhalten wir die Dokumente, die bereits mit den aus dem Rezensionsinhalt generierten Feldern angereichert sind.</p><p>Das Modell ermittelt die vorherrschende Stimmung (positiv, neutral oder negativ), generiert prägnante Zusammenfassungen, extrahiert relevante Schlüsselwörter und schätzt die Authentizität jeder Rezension ein. Diese Felder helfen dabei, die Meinung des Kunden zu verstehen, ohne den gesamten Text lesen zu müssen.</p><p>Zur Interpretation der Ergebnisse betrachten wir Folgendes:</p><ul><li><p>Sentiment, das die allgemeine Wahrnehmung des Produkts durch den Konsumenten widerspiegelt.</p></li><li><p>Die Zusammenfassung, in der die wichtigsten Punkte hervorgehoben werden.</p></li><li><p>Schlüsselwörter, die verwendet werden können, um ähnliche Rezensionen zu gruppieren oder Feedbackmuster zu identifizieren.</p></li><li><p>Authentizität, die ein Indikator dafür ist, ob die Rezension vertrauenswürdig erscheint. Dies ist nützlich für die Kuratierung oder Moderation.</p></li></ul>   "hits": [
      {
        "_index": "products",
        "_id": "1",
        "_score": 1,
        "_ignored": [
          "review.keyword"
        ],
        "_source": {
          "product": "Pampers Pants Premium Care Fralda",
          "model_id": "bedrock_completion_amazon_nova-lite",
          "review_analyze": {
            "summary": "The reviewer praises the diaper for its great material, high cotton content, and leak-proof design, especially highlighting its effectiveness for their baby.",
            "sentiment": "positive",
            "keywords": [
              "best diaper",
              "great material",
              "cotton",
              "no plastic",
              "leak-proof",
              "baby",
              "effective"
            ],
            "authenticity": "authentic"
          },
          "review": "Best diaper ever! Great material, lots of cotton, without all that plastic. Doesn't leak! My baby is a boy and every diaper leaked around the waist, this model solved the problem. Even on a small baby it's worth the effort of putting on the short diaper. I put it on my baby at 9 pm and only take it off in the morning, without any leaks."
        }
      },
      {
        "_index": "products",
        "_id": "2",
        "_score": 1,
        "_source": {
          "product": "Portable Electric Body Massager",
          "model_id": "bedrock_completion_amazon_nova-lite",
          "review_analyze": {
            "summary": "The product broke in three months for no apparent reason and the reviewer does not recommend it due to its short lifespan.",
            "sentiment": "negative",
            "keywords": [
              "broke",
              "short lifespan",
              "not recommend"
            ],
            "authenticity": "authentic"
          },
          "review": "It broke in three months for no apparent reason, thank goodness I didn't review it before. I don't recommend buying it because it has a short lifespan."
        }
      },
      {
        "_index": "products",
        "_id": "3",
        "_score": 1,
        "_ignored": [
          "review.keyword"
        ],
        "_source": {
          "product": "Havit Fuxi-H3 Black Quad-Mode Wired and Wireless Gaming Headset",
          "model_id": "bedrock_completion_amazon_nova-lite",
          "review_analyze": {
            "summary": "The headset has good sound quality for the price but suffers from poor connectivity, especially when using the microphone or moving the headset. It also has compatibility issues with Linux.",
            "sentiment": "negative",
            "keywords": [
              "sound",
              "connectivity",
              "microphone",
              "compatibility",
              "annoying",
              "turn off and on",
              "Linux",
              "flexible stem",
              "work from home"
            ],
            "authenticity": "authentic"
          },
          "review": "The sound is good for the price, but the connectivity is horrible. You always need to be playing audio, otherwise it loses connection (I work from home, and this is very annoying). Sometimes it loses connection and you have to turn it off and on again to get it back on. The microphone is very sensitive, so it loses connection frequently and you have to turn the headset off and on for the microphone to work again. The flexibility of the stem is useless, because if you move it, the microphone can turn off. Sometimes I need to use Linux and the headset simply doesn't work. It's light and comfortable, the sound is adequate, but the connectivity is terrible."
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 1,
        "_ignored": [
          "review.keyword"
        ],
        "_source": {
          "product": "Air Fryer 4L Oil Free Fryer Mondial",
          "model_id": "bedrock_completion_amazon_nova-lite",
          "review_analyze": {
            "summary": "The product offers value for money but has issues with peeling, rusting, and uneven frying.",
            "sentiment": "negative",
            "keywords": [
              "value for money",
              "peeling",
              "rusting",
              "uneven frying",
              "weaker in the middle"
            ],
            "authenticity": "authentic"
          },
          "review": "For those looking for value for money, it's a good option, but the tray (which is underneath the perforated basket) is already peeling a lot. My mother has one just like it and said that hers is even rusting, in other words, the material is MUCH inferior. There's also something that bothers me, because it looks like a microwave, it doesn't fry evenly, it's weaker in the middle and stronger on the sides. Buy at your own risk."
        }
      }
    ]<h2>Fazit</h2><p>Die Integration von Amazon Nova Lite und Elasticsearch demonstrierte, wie Sprachmodelle Rohrezensionen in strukturierte und wertvolle Informationen umwandeln können. Durch die Verarbeitung der Rezensionen mittels einer Pipeline konnten wir Stimmungsanalyse, Authentizität, Zusammenfassungen und Schlüsselwörter automatisch und konsistent extrahieren.</p><p>Die Ergebnisse zeigen, dass das Modell den Kontext der Rezensionen verstehen, Nutzermeinungen klassifizieren und die relevantesten Punkte jeder Erfahrung hervorheben kann. Dadurch entsteht ein wesentlich umfangreicherer Datensatz, der zur Verbesserung der Suchfunktionen genutzt werden kann.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/amazon-nova-models-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/amazon-nova-models-elasticsearch</guid>
    <category><![CDATA[KI]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdbbf13eb690294f1/6a17fddd6df73195190a115a/304713c48b568e17d0bb56b19edb28769f7801b3-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 02 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[So automatisieren Sie Synonyme und laden diese mithilfe unserer Synonym-API hoch.]]></title>
    <description><![CDATA[Erfahren Sie, wie LLMs verwendet werden können, um Synonyme automatisch zu identifizieren und zu generieren, sodass Begriffe programmatisch in die Elasticsearch-Synonym-API geladen werden können.]]></description>
    <content:encoded><![CDATA[<p>Die Verbesserung der Qualität der Suchergebnisse ist unerlässlich für ein effizientes Nutzererlebnis. Eine Möglichkeit zur Optimierung von Suchanfragen besteht darin, die abgefragten Begriffe automatisch durch Synonyme zu erweitern. Dies ermöglicht eine breitere Interpretation von Anfragen, berücksichtigt sprachliche Variationen und verbessert so die Ergebnisübereinstimmung.</p><p>Dieser Blogbeitrag untersucht, wie große Sprachmodelle (LLMs) verwendet werden können, um Synonyme automatisch zu identifizieren und zu generieren, sodass diese Begriffe programmatisch in die Synonym-API von Elasticsearch geladen werden können.</p><h2>Wann verwendet man Synonyme?</h2><p>Die Verwendung von Synonymen kann im Vergleich zur Vektorsuche eine schnellere und kostengünstigere Lösung sein. Die Implementierung ist einfacher, da sie keine tiefgreifenden Kenntnisse über Einbettungen oder einen komplexen Vektor-Ingestionsprozess erfordert.</p><p>Darüber hinaus ist der Ressourcenverbrauch geringer, da die Vektorsuche für die Einbettungsindizierung und den Abruf eine größere Speicherkapazität und einen größeren Arbeitsspeicher benötigt.</p><p>Ein weiterer wichtiger Aspekt ist die Regionalisierung der Suche. Mithilfe von Synonymen ist es möglich, Begriffe an die jeweilige Sprache und die lokalen Gepflogenheiten anzupassen. Dies ist in Situationen nützlich, in denen Einbettungen möglicherweise nicht mit regionalen Ausdrücken oder länderspezifischen Begriffen übereinstimmen. Beispielsweise können manche Wörter oder Akronyme je nach Region unterschiedliche Bedeutungen haben, werden aber von den lokalen Nutzern selbstverständlich als Synonyme behandelt. In Brasilien ist das recht üblich. „Abacaxi“ und „ananás“ bezeichnen die gleiche Frucht (Ananas), wobei der zweite Begriff in einigen Regionen des Nordostens gebräuchlicher ist. Ähnlich verhält es sich mit dem im Südosten bekannten „pão francês“, das im Nordosten als „pão careca“ bekannt ist.</p><h2>Wie kann man LLMs verwenden, um Synonyme zu generieren?</h2><p>Um Synonyme automatisch zu erhalten, können wir LLMs verwenden, die den Kontext eines Begriffs analysieren und passende Variationen vorschlagen. Dieser Ansatz ermöglicht die dynamische Erweiterung von Synonymen und gewährleistet so eine umfassendere und genauere Suche, ohne auf ein festes Wörterbuch angewiesen zu sein.</p><p>In dieser Demonstration verwenden wir ein LLM, um Synonyme für E-Commerce-Produkte zu generieren. Viele Suchanfragen liefern aufgrund von Variationen in den Suchbegriffen nur wenige oder gar keine Ergebnisse. Mit Synonymen können wir dieses Problem lösen. Eine Suche nach „Smartphone“ kann beispielsweise verschiedene Modelle von Mobiltelefonen umfassen, um sicherzustellen, dass die Nutzer die Produkte finden, die sie suchen.</p><h3>Voraussetzungen</h3><p>Bevor wir beginnen, müssen wir die Umgebung einrichten und die erforderlichen Abhängigkeiten definieren. Wir werden die von Elastic bereitgestellte Lösung nutzen, um <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">Elasticsearch und Kibana lokal in Docker auszuführen</a>. Der Code wird in Python, Version 3.9.6, mit folgenden Abhängigkeiten geschrieben:</p>pip install openai==1.59.8 elasticsearch==8.15.1<h3>Erstellung des Produktindex</h3><p>Zunächst erstellen wir einen Index der Produkte ohne Synonymunterstützung. Dies ermöglicht es uns, Abfragen zu validieren und sie dann mit einem Index zu vergleichen, der Synonyme enthält.</p><p>Um den Index zu erstellen, laden wir einen Produktdatensatz per Massenimport mit folgendem Befehl in den Kibana DevTools:</p>POST _bulk
{"index": {"_index": "products", "_id": 10001}}
{"category": "Electronics", "name": "iPhone 14 Pro"}
{"index": {"_index": "products", "_id": 10007}}
{"category": "Electronics", "name": "MacBook Pro 16-inch"}
{"index": {"_index": "products", "_id": 10013}}
{"category": "Electronics", "name": "Samsung Galaxy Tab S8"}
{"index": {"_index": "products", "_id": 10037}}
{"category": "Electronics", "name": "Apple Watch Series 8"}
{"index": {"_index": "products", "_id": 10049}}
{"category": "Electronics", "name": "Kindle Paperwhite"}
{"index": {"_index": "products", "_id": 10067}}
{"category": "Electronics", "name": "Samsung QLED 4K TV"}
{"index": {"_index": "products", "_id": 10073}}
{"category": "Electronics", "name": "HP Spectre x360 Laptop"}
{"index": {"_index": "products", "_id": 10079}}
{"category": "Electronics", "name": "Apple AirPods Pro"}
{"index": {"_index": "products", "_id": 10115}}
{"category": "Electronics", "name": "Amazon Echo Show 10"}
{"index": {"_index": "products", "_id": 10121}}
{"category": "Electronics", "name": "Apple iPad Air"}
{"index": {"_index": "products", "_id": 10127}}
{"category": "Electronics", "name": "Apple AirPods Max"}
{"index": {"_index": "products", "_id": 10151}}
{"category": "Electronics", "name": "Sony WH-1000XM4 Headphones"}
{"index": {"_index": "products", "_id": 10157}}
{"category": "Electronics", "name": "Google Pixel 6 Pro"}
{"index": {"_index": "products", "_id": 10163}}
{"category": "Electronics", "name": "Apple MacBook Air"}
{"index": {"_index": "products", "_id": 10181}}
{"category": "Electronics", "name": "Google Pixelbook Go"}
{"index": {"_index": "products", "_id": 10187}}
{"category": "Electronics", "name": "Sonos Beam Soundbar"}
{"index": {"_index": "products", "_id": 10199}}
{"category": "Electronics", "name": "Apple TV 4K"}
{"index": {"_index": "products", "_id": 10205}}
{"category": "Electronics", "name": "Samsung Galaxy Watch 4"}
{"index": {"_index": "products", "_id": 10211}}
{"category": "Electronics", "name": "Apple MacBook Pro 16-inch"}
{"index": {"_index": "products", "_id": 10223}}
{"category": "Electronics", "name": "Amazon Echo Dot (4th Gen)"}<h3>Synonyme mit LLM generieren</h3><p>In diesem Schritt verwenden wir ein LLM, um dynamisch Synonyme zu generieren. Um dies zu erreichen, werden wir die OpenAI-API integrieren und ein geeignetes Modell sowie eine entsprechende Eingabeaufforderung definieren. Der LLM erhält die Produktkategorie und den Produktnamen, wobei darauf geachtet wird, dass die Synonyme kontextuell relevant sind.</p>import json
import logging

from openai import OpenAI

def call_gpt(prompt, model):
    try:
        logging.info("generate synonyms by llm...")
        response = client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.7,
            max_tokens=1000
        )
        content = response.choices[0].message.content.strip()
        return content
    except Exception as e:
        logging.error(f"Failed to use model: {e}")
        return None

def generate_synonyms(category, products):
   synonyms = {}

   for product in products:
       prompt = f"You are an expert in generating synonyms for products. Based on the category and product name provided, generate synonyms or related terms. Follow these rules:\n"
       prompt += "1. **Format**: The first word should be the main item (part of the product name, excluding the brand), followed by up to 3 synonyms separated by commas.\n"
       prompt += "2. **Exclude the brand**: Do not include the brand name in the synonyms.\n"
       prompt += "3. **Maximum synonyms**: Generate a maximum of 3 synonyms per product.\n\n"
       prompt += f"The category is: **{category}**, and the product is: **{product}**. Return only the synonyms in the requested format, without additional explanations."

       response = call_gpt(prompt, "gpt-4o")
       synonyms[product] = response

   return synonyms<p>Aus dem erstellten Produktindex rufen wir alle Artikel der Kategorie „Elektronik“ ab und senden deren Namen an das LLM. Die erwartete Ausgabe sieht in etwa so aus:</p>{
  "iPhone 14 Pro": ["iPhone", "smartphone", "mobile", "handset"],
  "MacBook Pro 16-inch": ["MacBook", "Laptop", "Notebook", "Ultrabook"],
  "Samsung Galaxy Tab S8": ["Tab", "Tablet", "Slate", "Pad"],
  "Bose QuietComfort 35 Headphones": ["Headphones", "earphones", "earbuds", "headset"]
}<p>Mit den generierten Synonymen können wir diese mithilfe der Synonyms API in Elasticsearch registrieren.</p><h3>Synonyme mit der Synonyms-API verwalten</h3><p>Die Synonyms-API bietet eine effiziente Möglichkeit, Synonymgruppen direkt im System zu verwalten. Jedes Synonymset besteht aus Synonymregeln, nach denen eine Gruppe von Wörtern bei Suchanfragen als gleichwertig behandelt wird.</p><p><strong>Beispiel für die Erstellung eines Synonymsets</strong></p>PUT _synonyms/my-synonyms-set
{
  "synonyms_set": [
    {
      "id": "rule-1",
      "synonyms": "hello, hi"
    },
    {
      "synonyms": "bye, goodbye"
    }
  ]
}<p>
Dadurch entsteht eine Menge namens „meine-Synonyme-Menge“, in der „hello“ und „hi“ sowie „bye“ und „goodbye“ als gleichwertig behandelt werden.</p><h2>Implementierung der Synonymerstellung für den Produktkatalog</h2><p>Nachfolgend ist die Methode aufgeführt, die für den Aufbau eines Synonymsets und dessen Einfügen in Elasticsearch zuständig ist. Die Synonymregeln werden auf der Grundlage der vom LLM vorgeschlagenen Synonymzuordnung generiert. Jede Regel hat eine ID, die dem Produktnamen im Slug-Format entspricht, und die vom LLM berechnete Liste der Synonyme.</p>import json
import logging

from elasticsearch import Elasticsearch
from slugify import slugify

es = Elasticsearch(
    "http://localhost:9200",
    api_key="your_api_key"
)

def mount_synonyms(results):
   synonyms_set = [{"id": slugify(product), "synonyms": synonyms} for product, synonyms in
                   results.items()]

   try:
       response = es.synonyms.put_synonym(id="products-synonyms-set",
                                                 synonyms_set=synonyms_set)

       logging.info(json.dumps(response.body, indent=4))
       return response.body
   except Exception as e:
       logging.error(f"Error create synonyms: {str(e)}")
       return None<p>Nachfolgend die Anfragenutzlast zum Erstellen des Synonymsets:</p>{
   "synonyms_set":[
      {
         "id": "iphone-14-pro",
         "synonyms": "iPhone, smartphone, mobile, handset"
      },
      {
         "id": "macbook-pro-16-inch",
         "synonyms": "MacBook, Laptop, Notebook, Computer"
      },
      {
         "id": "samsung-galaxy-tab-s8",
         "synonyms": "Tablet, Slate, Pad, Device"
      },
      {
         "id": "garmin-forerunner-945",
         "synonyms": "Forerunner, smartwatch, fitness watch, GPS watch"
      },
      {
         "id": "bose-quietcomfort-35-headphones",
         "synonyms": "Headphones, Earphones, Headset, Cans"
      }
   ]
}<p>Nachdem im Cluster ein Synonymset erstellt wurde, können wir zum nächsten Schritt übergehen, nämlich der Erstellung eines neuen Index mit Synonymunterstützung unter Verwendung des definierten Sets.</p><p>Der vollständige Python-Code mit den von LLM generierten Synonymen und der durch die Synonyms-API definierten Erstellung von Synonymsätzen ist unten aufgeführt:</p>import json
import logging

from elasticsearch import Elasticsearch
from openai import OpenAI
from slugify import slugify

logging.basicConfig(level=logging.INFO)

client = OpenAI(
   api_key="your-key",
)

es = Elasticsearch(
    "http://localhost:9200",
    api_key="your_api_key"
)


def call_gpt(prompt, model):
   try:
       logging.info("generate synonyms by llm...")
       response = client.chat.completions.create(
           model=model,
           messages=[{"role": "user", "content": prompt}],
           temperature=0.7,
           max_tokens=1000
       )
       content = response.choices[0].message.content.strip()
       return content
   except Exception as e:
       logging.error(f"Failed to use model: {e}")
       return None


def generate_synonyms(category, products):
   synonyms = {}

   for product in products:
       prompt = f"You are an expert in generating synonyms for products. Based on the category and product name provided, generate synonyms or related terms. Follow these rules:\n"
       prompt += "1. **Format**: The first word should be the main item (part of the product name, excluding the brand), followed by up to 3 synonyms separated by commas.\n"
       prompt += "2. **Exclude the brand**: Do not include the brand name in the synonyms.\n"
       prompt += "3. **Maximum synonyms**: Generate a maximum of 3 synonyms per product.\n\n"
       prompt += f"The category is: **{category}**, and the product is: **{product}**. Return only the synonyms in the requested format, without additional explanations."

       response = call_gpt(prompt, "gpt-4o")
       synonyms[product] = response

   return synonyms


def get_products(category):
   query = {
       "size": 50,
       "_source": ["name"],
       "query": {
           "bool": {
               "filter": [
                   {
                       "term": {
                           "category.keyword": category
                       }
                   }
               ]
           }
       }
   }
   response = es.search(index="products", body=query)

   if response["hits"]["total"]["value"] &gt; 0:
       product_names = [hit["_source"]["name"] for hit in response["hits"]["hits"]]
       return product_names
   else:
       return []


def mount_synonyms(results):
   synonyms_set = [{"id": slugify(product), "synonyms": synonyms} for product, synonyms in
                   results.items()]

   try:
       es_client = get_client_es()
       response = es_client.synonyms.put_synonym(id="products-synonyms-set",
                                                 synonyms_set=synonyms_set)

       logging.info(json.dumps(response.body, indent=4))
       return response.body
   except Exception as e:
       logging.error(f"Erro update synonyms: {str(e)}")
       return None


if __name__ == '__main__':
   category = "Electronics"
   products = get_products("Electronics")
   llm_synonyms = generate_synonyms(category, products)
   mount_synonyms(llm_synonyms)<h3>Erstellen eines Index mit Synonymunterstützung</h3><p>Es wird ein neuer Index erstellt, in dem alle Daten aus dem Index <code>products</code> neu indiziert werden. Dieser Index verwendet <code>synonyms_filter</code>, der den zuvor erstellten <code>products-synonyms-set</code> anwendet.</p><p>Nachfolgend die Indexzuordnung, die für die Verwendung von Synonymen konfiguriert ist:</p>PUT products_02
{
  "settings": {
    "analysis": {
      "filter": {
        "synonyms_filter": {
          "type": "synonym",
          "synonyms_set": "products-synonyms-set",
          "updateable": true
        }
      },
      "analyzer": {
        "synonyms_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "synonyms_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "ID": {
        "type": "long"
      },
      "category": {
        "type": "keyword"
      },
      "name": {
        "type": "text",
        "analyzer": "standard",
        "search_analyzer": "synonyms_analyzer"
      }
    }
  }
}<h3>Neuindizierung des Index <code>products</code></h3><p>Nun werden wir die <strong>Reindex-API</strong> verwenden, um die Daten vom Index <code>products</code> in den neuen Index <code>products_02</code> zu migrieren, der auch Synonymunterstützung beinhaltet. Der folgende Code wurde in den Kibana DevTools ausgeführt:
</p>POST _reindex
{
  "source": {
    "index": "products"
  },
  "dest": {
    "index": "products_02"
  }
}<p>Nach der Migration wird der Index <code>products_02</code> gefüllt sein und kann Suchanfragen mithilfe des konfigurierten Synonymsets validieren.</p><h3>Suche mit Synonymen validieren</h3><p>Lassen Sie uns die Suchergebnisse der beiden Indizes vergleichen. Wir werden die gleiche Abfrage auf beiden Indizes ausführen und überprüfen, ob die Synonyme verwendet werden, um Ergebnisse abzurufen.</p><h4>Suche im Index <code>products</code> (ohne Synonyme)</h4><p>Wir werden Kibana verwenden, um Suchvorgänge durchzuführen und die Ergebnisse zu analysieren. Im Menü „Analytics &gt; Discovery“ erstellen wir eine Datenansicht, um die Daten aus den von uns erstellten Indizes zu visualisieren.</p><p>Klicken Sie innerhalb von Discovery auf Datenansicht und definieren Sie einen Namen und ein Indexmuster. Für den Index "<strong>Produkte</strong>" verwenden wir das Muster "<strong>Produkte</strong> ". Anschließend wiederholen wir den Vorgang, um eine neue Datenansicht für den Index "<strong>products_02</strong>" zu erstellen, wobei wir das Muster "<strong>products_02 "</strong> verwenden.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte826fd932cfeb9df/6a17fdffec0f8912aa5a6841/3ad4a6891a3905e96532a312932fdf3a8216aec2-1600x599.png" alt="" /><p>Nachdem die Datenansichten konfiguriert sind, können wir zu Analytics &gt; Discovery zurückkehren und die Validierungen starten.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltba3729c60068e8a0/6a17fe01e9ea87ba2aa9c82a/422c4b2b51abae6580cad25085d1b8a365fc6b9e-1294x850.png" alt="" /><p>Hier erhalten wir nach Auswahl der DataView-Produkte und einer Suche nach dem Begriff „Tablet“ keine Ergebnisse, obwohl wir wissen, dass es Produkte wie „Kindle Paperwhite“ und „Apple iPad Air“ gibt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2c6a383dd4cb0157/6a17fe02577262671d1bce0c/e4ae3a785fdd93f48d7c7d204185ded149126f2c-1600x862.png" alt="" /><h4>Suche im Index <code>products_02</code> (unterstützt Synonyme)</h4><p>Bei der Durchführung derselben Abfrage in der Datenansicht "<strong>products_synonyms</strong>", die Synonyme unterstützt, wurden die Produkte erfolgreich abgerufen. Dies beweist, dass die konfigurierte Synonymgruppe korrekt funktioniert und sicherstellt, dass verschiedene Variationen der Suchbegriffe die erwarteten Ergebnisse liefern.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt986b4706e2f70014/6a17fe043e9e454edbba16d3/e609749c39e90d5c82fa846af6124679dd62bcb8-1600x526.png" alt="" /><p>Das gleiche Ergebnis lässt sich erzielen, indem man dieselbe Abfrage direkt in den Kibana DevTools ausführt. Suchen Sie einfach im Index products_02 mithilfe der Elasticsearch Search API:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe829a3c4d7aac60/6a17fe05e8fbce03d73a1bd7/504d0d1f96dcfbceb309063dc0716bcee64ad2f8-1600x870.png" alt="" /><h2>Fazit</h2><p>Die Implementierung von Synonymen in Elasticsearch verbesserte die Genauigkeit und Abdeckung der Produktkatalogsuche. Der entscheidende Unterschied bestand in der Verwendung eines <strong>LLM</strong>, das Synonyme automatisch und kontextbezogen generierte, wodurch die Notwendigkeit vordefinierter Listen entfiel. Das Modell analysierte Produktnamen und Kategorien und stellte dabei relevante Synonyme für den E-Commerce sicher.</p><p>Darüber hinaus vereinfachte die <strong>Synonyms-API</strong> die Wörterbuchverwaltung, sodass Synonymsätze dynamisch geändert werden können. Mit diesem Ansatz wurde die Suche flexibler und besser an unterschiedliche Suchanfragen der Nutzer anpassbar.</p><p>Dieser Prozess kann durch neue Daten und Modellanpassungen kontinuierlich verbessert werden, wodurch ein immer effizienteres Forschungserlebnis gewährleistet wird.</p><h2>Referenzen</h2><p><strong>Elasticsearch lokal ausführen</strong></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html</a></p><p><strong>Synonyms API</strong></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/synonyms-apis.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/synonyms-apis.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-synonyms-automate</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-synonyms-automate</guid>
    <category><![CDATA[Relevanz]]></category>
    <category><![CDATA[Grundlagen]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f0247b9bc1d1ccd/6a17fe07ec0f891c745a6845/05a3cfeaa387561d5334ca3f1609035ddfff7481-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 27 Mar 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[Facettensuche: KI zur Verbesserung des Suchumfangs und der Suchergebnisse]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie mit der Facettensuche in Elasticsearch die Optionen innerhalb von Kategorien schnell eingrenzen können.]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel werden wir untersuchen, wie künstliche Intelligenz (KI), insbesondere durch den Einsatz fortschrittlicher Sprachmodelle wie GPT-4, dazu beitragen kann, mehr kontextbezogene Aspekte zu schaffen und diese dadurch für die Nutzer noch relevanter und nützlicher zu machen.</p><p>Die Facettensuche ist ein leistungsstarkes Werkzeug in E-Commerce-Plattformen. Es hilft dabei, Suchergebnisse anhand der Eigenschaften der angezeigten Elemente zu organisieren und zu verfeinern. Facetten werden zwar oft mit Filtern verwechselt, funktionieren aber anders. Filter sind feste Attribute, die durch Informationen definiert werden, die immer im Index vorhanden sind, wie zum Beispiel die Kategorie oder das Format eines Produkts. Facetten hingegen sind dynamisch und werden aus den Ergebnissen der ausgeführten Suche generiert.</p><p>Stellen Sie sich einen Bekleidungskatalog vor: Felder wie „Kategorie“ (z. B. T-Shirts, Hosen) oder „Geschlecht“ (z. B. männlich, weiblich) sind Filter, die dabei helfen, die Ergebnisse einzugrenzen. Die Facetten spiegeln jedoch spezifische Eigenschaften der in den Ergebnissen angezeigten Produkte wider, wie z. B. gängige Farben, verfügbare Größen oder Materialien. Dies ermöglicht ein anpassungsfähigeres und kontextbezogeneres Sucherlebnis.</p><p>Unten sehen Sie ein Bild, auf dem wir mit einem Filter interagieren und die danach gefilterten Suchergebnisse sehen können.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc4ce8ca7e5b62ad7/6a17f8ba6864a4534bb68979/74d2159706ab7248ebe5efddc74c882f0693db71-600x420.gif" alt="Beispiel für eine Facettensuche" /><h2>Wie KI die Facettengenerierung verbessern kann</h2><p>Künstliche Intelligenz wird oft mit semantischer Suche und Einbettungen in Verbindung gebracht, aber was ist mit Facetten? Wie kann KI genutzt werden, um Facetten für jede Suche nützlicher und kontextspezifischer zu gestalten?</p><p>Eine interessante Möglichkeit besteht darin, mithilfe von KI neue Kategorisierungen zu erstellen, die über die traditionellen Klassifizierungen im Index hinausgehen. Durch die Analyse spezifischer Merkmale des Inhalts können diese neuen Kategorien eine reichhaltigere und präzisere Kontextualisierung ermöglichen, wodurch die einzelnen Aspekte relevanter und besser auf die Bedürfnisse der Nutzer abgestimmt werden. Dies ermöglicht eine aussagekräftigere Verfeinerung der Ergebnisse im Vergleich zu den ursprünglichen Dokumentenkategorien.</p><h2>Wie KI die Filmklassifizierung für bessere Suchergebnisse verfeinern kann</h2><p>Lassen Sie uns die folgenden Filme analysieren, die alle aktuell dem Genre Drama zugeordnet sind:</p><ul><li><p>Requiem für einen Traum
 Zusammenfassung: Die drogeninduzierten Utopien von vier Bewohnern von Coney Island zerbrechen, als ihre Sucht immer tiefer wird.</p></li><li><p>Amerikanische Schönheit
 Zusammenfassung: Ein sexuell frustrierter Vorstadtvater gerät in eine Midlife-Crisis, nachdem er sich in die beste Freundin seiner Tochter verliebt hat.</p></li><li><p>Good Will Hunting
 Kurzfassung: Will Hunting, ein Hausmeister am MIT, hat ein Talent für Mathematik, braucht aber die Hilfe eines Psychologen, um in seinem Leben eine Richtung zu finden.</p></li></ul><p>Diese Genreklassifizierung erfasst weder die subtilen Unterschiede noch die einzigartigen Kontexte der einzelnen Filme. Durch den Einsatz von KI zur Analyse von Inhaltsangaben und zentralen Themen können wir neue Kategorien erstellen, die den wahren Kontext jedes Films besser widerspiegeln. Zum Beispiel:</p><ul><li><p>Requiem für einen Traum – Neue Kategorie: „Sucht und Abhängigkeit“</p></li><li><p>American Beauty – Neue Kategorie: „Midlife-Crisis“</p></li><li><p>Good Will Hunting – Neue Kategorie: „Intellektueller Kampf“</p></li></ul><p>Durch diese neuen Kategorien werden die Suchergebnisse wesentlich präziser und bieten den Nutzern gleichzeitig aussagekräftigere Filter zur Verfeinerung ihrer Ergebnisse. Dieser Ansatz ist besonders effektiv, wenn die ursprünglichen Kategorien zu allgemein gehalten sind, da er es den Nutzern ermöglicht, leichter genau das zu finden, wonach sie suchen.</p><h2>Erstellen neuer Kategorien mit GPT-4: Beispiel für die Facettensuche</h2><p>In diesem Beispiel zeigen wir, wie ein KI-Modell verwendet werden kann, um neue Filmkategorien zu erstellen, die präziser sind und besser auf den Kontext des jeweiligen Werkes abgestimmt sind. Um diesen Prozess zu demonstrieren, werden wir die Elastic-Simulationspipeline zusammen mit dem OpenAI-Inferenzdienst verwenden. Es wird eine Pipeline mit mehreren Prozessoren erstellt, darunter der Skriptprozessor, der für die Erstellung der Eingabeaufforderung zuständig ist, die im Inferenzprozessor ausgeführt werden soll und die neuen Kategorien bestimmen kann. Die anderen Prozessoren werden verwendet, um die während der Pipeline-Ausführung erzeugten Daten und Hilfsfelder zu bearbeiten. Erwähnenswert ist, dass diese Logik auch auf andere ähnliche Werkzeuge oder Modelle angewendet werden kann.</p><p>Als erstes müssen wir den Inferenz-Endpunkt erstellen, in dem wir den Dienst als OpenAI, das für den Zugriff auf den Dienst erforderliche Token und das Modell definieren. In diesem Beispiel verwende ich gpt-4o-mini. Für weitere Details zum OpenAI-Inferenzdienst klicken Sie <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-openai.html">hier</a>.</p>PUT _inference/completion/generate_topics_ia
{
    "service": "openai",
    "service_settings": {
        "api_key": "your-token",
        "model_id": "gpt-4o-mini"
    }
}<p>Nachdem der Endpunkt erstellt wurde, können wir ihn nun verwenden, um die neuen Kategorien zu erstellen. Nachfolgend finden Sie eine Pipeline, die den gesamten Prozess der Dokumentendatenmanipulation und der Generierung von Eingabeaufforderungen übernimmt. Ich werde die Funktion jedes Prozessors im Detail erläutern.</p><p>Der erste Prozessor ist für die Erstellung der Eingabeaufforderung zuständig. Es ist sehr wichtig, die Anweisungen klar und detailliert zu formulieren, damit die KI die Themen korrekt analysieren und identifizieren kann. In dieser Aufgabenstellung bitte ich um zwei Themen, die auf der Analyse von Titel, Beschreibung und Genre der Filme basieren.</p>{
        "script": {
          "source": """
            ctx.prompt = "You are an expert in semantic analysis and audiovisual content categorization. Your task is to generate only subcategories (max 2 topics) that describe specific aspects of movies based on their genres and descriptions. The output should be like: 'n1, n2, ...n'. Here is a movie info to analyze: Title: " + ctx.title  + "Genres: " + ctx.genres  + "Description: " + ctx.description;
          """
        }<p>Die nächste Pipeline ist die Inferenzpipeline. Sie empfängt die Eingabeaufforderung und sendet sie an unseren <strong>generate_topics_ia-</strong> Endpunkt. Die vom Modell generierte Antwort wird im Ergebnisfeld gespeichert.</p>{
        "inference": {
          "model_id": "generate_topics_ia",
          "input_output": {
            "input_field": "prompt",
            "output_field": "result"
          }
        }
      }<p>Als Nächstes werden 3 Prozessoren verwendet, um die Antwort zu bearbeiten und sie im Themenfeld festzulegen, zusätzlich zum Entfernen temporärer Felder, die ich erstellt habe.</p><p>Bei der Ausführung dieser Pipeline erhalten wir die folgenden Ergebnisse:</p>{
  "docs": [
    {
      "doc": {
        "_index": "index",
        "_version": "-3",
        "_id": "1",
        "_source": {
          "description": "While Frodo and Sam edge closer to Mordor with the help of the shifty Gollum, the divided fellowship makes a stand against Sauron's new ally, Saruman, and his hordes of Isengard.",
          "model_id": "generate_topics_ia",
          "title": "The Lord of the Rings: The Fellowship of the Ring",
          "genres": [
            "Action",
            "Adventure",
            "Drama"
          ],
          "topics": [
            "Fantasy",
            "Quest"
          ]
        },
        "_ingest": {
          "timestamp": "2024-11-22T17:51:51.340010257Z"
        }
      }
    },
    {
      "doc": {
        "_index": "index",
        "_version": "-3",
        "_id": "2",
        "_source": {
          "description": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
          "model_id": "generate_topics_ia",
          "title": "Interstellar",
          "genres": [
            "Adventure",
            "Drama",
            "Sci-Fi"
          ],
          "topics": [
            "space exploration",
            "human survival"
          ]
        },
        "_ingest": {
          "timestamp": "2024-11-22T17:51:51.340413173Z"
        }
      }
    },
    {
      "doc": {
        "_index": "index",
        "_version": "-3",
        "_id": "3",
        "_source": {
          "description": "An astronaut becomes stranded on Mars after his team assume him dead, and must rely on his ingenuity to find a way to signal to Earth that he is alive.",
          "model_id": "generate_topics_ia",
          "title": "The Martian",
          "genres": [
            "Adventure",
            "Drama",
            "Sci-Fi"
          ],
          "topics": [
            "survival",
            "ingenuity"
          ]
        },
        "_ingest": {
          "timestamp": "2024-11-22T17:51:51.340427965Z"
        }
      }
    }
  ]
}<p>Beachten Sie, dass wir neue Kategorien haben, die stärker mit dem Kontext der Filme zusammenhängen, auch wenn einige ursprünglich aus demselben Genre stammen.</p><p>Wir können diese neuen Kategorien nun verwenden und sie zusammen mit dem Dokument indexieren. Auf diese Weise erhalten wir bei der Erstellung der Facetten neben der Hauptkategorie auch spezifischere Unterkategorien, die auf den Kontext der Filme abgestimmt sind.</p><p>Darüber hinaus ist es möglich, diese neuen Kategorien zu vektorisieren und sie in Vektorsuchen zu verwenden. Dies bedeutet, dass die neuen Kategorien nicht nur als Filter dienen, sondern auch zur Berechnung semantischer Ähnlichkeiten mit den Suchbegriffen verwendet werden können, wodurch die Relevanz der präsentierten Ergebnisse weiter erhöht wird.</p><p>Vollständige Pipeline:</p>POST /_ingest/pipeline/_simulate
{
  "pipeline": {
    "processors": [
      {
        "script": {
          "source": """
            ctx.prompt = "You are an expert in semantic analysis and audiovisual content categorization. Your task is to generate only subcategories (max 2 topics) that describe specific aspects of movies based on their genres and descriptions. The output should be like string: 'n1, n2m ...n'. Here is a movies info to analyze: Title: " + ctx.title  + "Genres: " + ctx.genres  + "Description: " + ctx.description;
          """
        }
      },
      {
        "inference": {
          "model_id": "generate_topics_ia",
          "input_output": {
            "input_field": "prompt",
            "output_field": "result"
          }
        }
      },
      {
        "split": {
          "field": "result",
          "target_field": "topics",
          "separator": ", "
        }
      },
      {
        "remove": {
          "field": "result"
        }
      },
      {
        "remove": {
          "field": "prompt"
        }
      }
    ]
  },
  "docs": [
    {
      "_index": "index",
      "_id": "1",
      "_source": {
        "title": "The Lord of the Rings: The Fellowship of the Ring",
        "description": "While Frodo and Sam edge closer to Mordor with the help of the shifty Gollum, the divided fellowship makes a stand against Sauron's new ally, Saruman, and his hordes of Isengard.",
        "genres": [
          "Action",
          "Adventure",
          "Drama"
        ]
      }
    },
    {
      "_index": "index",
      "_id": "2",
      "_source": {
        "title": "Interstellar",
        "description": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
        "genres": [
          "Adventure", "Drama", "Sci-Fi"
        ]
      }
    },
    {
      "_index": "index",
      "_id": "3",
      "_source": {
        "title": "The Martian",
        "description": "An astronaut becomes stranded on Mars after his team assume him dead, and must rely on his ingenuity to find a way to signal to Earth that he is alive.",
        "genres": [
          "Adventure", "Drama", "Sci-Fi"
        ]
      }
    }
  ]
}<h2>Fazit</h2><p>Der Einsatz von KI zur Verbesserung der Suchergebnisse kann das Sucherlebnis grundlegend verändern, indem die Ergebnisse spezifischer und kontextbezogener werden. Im Gegensatz zu festen Kategorien, die oft sehr allgemein gehalten sind, können KI-generierte Kategorien den Kontext besser widerspiegeln. Wenn wir beispielsweise Filme neu klassifizieren, können wir Kontextinformationen erfassen, die in den primären Kategorien fehlen, und so viel relevantere Gruppierungen vornehmen.</p><p>Diese neuen Kategorien können dem Index hinzugefügt werden, um nicht nur die Facettierung zu verbessern, sondern auch Vektorsuchen zu ermöglichen. Das Ergebnis ist ein effizienteres Sucherlebnis mit Filtern, die besser auf den Kontext abgestimmt sind.</p><h2>Referenzen</h2><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-openai.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-openai.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/simulate-pipeline-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/simulate-pipeline-api.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/script-processor.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/script-processor.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/faceted-search-examples-ai</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/faceted-search-examples-ai</guid>
    <category><![CDATA[KI]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd2838185214162c8/6a17f8bedbb4ff04affb58a5/25c9f9baa2326b5189ce0b1cc6240475781c755d-721x421.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 28 Jan 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 die Hybridsuche für einen E-Commerce-Produktkatalog nutzt]]></title>
    <description><![CDATA[Erfahren Sie, wie Sie mit Hilfe von Hybrid-Suche einen E-Commerce-Produktkatalog erstellen können, indem Sie Facettierung, Werbeaktionen, Personalisierung und Verhaltensanalysen einsetzen.]]></description>
    <content:encoded><![CDATA[<p>In diesem Artikel zeigen wir, wie man eine hybride Suche implementiert, die die Ergebnisse der Volltextsuche mit der Vektorsuche kombiniert. Durch die Vereinigung dieser beiden Ansätze verbessert die hybride Suche die Ergebnisbreite und nutzt die Vorteile beider Suchstrategien.</p><p>Neben der Integration der Hybridsuche zeigen wir Ihnen, wie Sie Funktionen hinzufügen können, die Ihre Suchlösung noch robuster machen. Dazu gehören Facettenmarketing und personalisierte Produktwerbung. Darüber hinaus zeigen wir Ihnen, wie Sie mit dem Behavioral Analytics Tool von Elastic Benutzerinteraktionen erfassen und wertvolle Erkenntnisse gewinnen können.</p><p>In dieser Implementierung sehen Sie, wie Sie sowohl die Benutzeroberfläche erstellen, die es Benutzern ermöglicht, die Suchergebnisse anzuzeigen und mit ihnen zu interagieren, als auch die API, die für die Rückgabe der Informationen zuständig ist. Die Links zu den Repositories mit dem Quellcode finden Sie unten:</p><ul><li><p><a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/product-store-search">https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/product-store-search</a></p></li><li><p><a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/app-product-store">https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/app-product-store</a> </p></li></ul><p>Wir haben diesen Leitfaden in mehrere Schritte unterteilt, von der Erstellung des Index bis hin zur Implementierung erweiterter Funktionen wie Facettierung und Ergebnispersonalisierung. Am Ende verfügen Sie über eine robuste Suchlösung, die Sie im E-Commerce einsetzen können.</p><h2>Umgebungseinrichtung für die hybride E-Commerce-Suche</h2><p>Bevor wir mit der Implementierung beginnen, müssen wir die Umgebung einrichten. Sie können entweder einen Dienst auf Elastic Cloud oder eine containerisierte Lösung zur Verwaltung von Elasticsearch nutzen. Wenn Sie sich für die Containerisierung entscheiden, finden Sie eine Konfiguration über Docker Compose in diesem Repository: <a href="https://github.com/andreluiz1987/product-store-search/blob/main/docker/docker-compose.yml">docker-compose.yml</a>.</p><h2>Indexerstellung und Produktkatalog-Einführung</h2><p>Der Index wird auf Basis eines Katalogs von Kosmetikprodukten erstellt, der Felder wie Name, Beschreibung, Foto, Kategorie und Schlagwörter enthält. Felder, die für die Volltextsuche verwendet werden, wie „Name“ und „Beschreibung“, werden als <code>text</code> abgebildet, während Felder, die für Aggregationen verwendet werden, wie „Kategorie“ und „Marke“, als <code>keyword</code> abgebildet werden, um die Facettierung zu ermöglichen.</p><p>Das Feld „Beschreibung“ wird für die Vektorsuche verwendet, da es mehr Kontextinformationen zu den Produkten liefert. Dieses Feld wird als <code>dense_vector,</code> definiert und speichert die Vektordarstellung der Beschreibung.</p><p>Die Indexzuordnung erfolgt wie folgt:</p>{
   "mappings":{
      "properties":{
         "id":{
            "type":"keyword"
         },
         "brand":{
            "type":"text",
            "fields":{
               "keyword":{
                  "type":"keyword"
               }
            }
         },
         "name":{
            "type":"text"
         },
         "price":{
            "type":"float"
         },
         "price_sign":{
            "type":"keyword"
         },
         "currency":{
            "type":"keyword"
         },
         "image_link":{
            "type":"keyword"
         },
         "description":{
            "type":"text"
         },
         "description_embeddings":{
            "type":"dense_vector",
            "dims":384
         },
         "rating":{
            "type":"keyword"
         },
         "category":{
            "type":"keyword"
         },
         "product_type":{
            "type":"keyword"
         },
         "tag_list":{
            "type":"keyword"
         }
      }
   }
}<p>Das Skript zur Erstellung des Indexes finden Sie <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/product-store-search/infra/create_index.py">hier</a>.</p><h2>Einbettungsgeneration</h2><p>Zur Vektorisierung der Produktbeschreibungen verwenden wir das Modell all-MiniLM-L6-v2. In diesem Fall ist die Anwendung für die Generierung der Einbettungen vor der Indizierung verantwortlich. Eine weitere Möglichkeit wäre, das Modell in den Elasticsearch-Cluster zu importieren, aber für diese lokale Umgebung haben wir uns dafür entschieden, die Vektorisierung direkt innerhalb der Anwendung durchzuführen.</p><p>Wir nutzten den auf <a href="https://www.kaggle.com/datasets/shivd24coder/cosmetic-brand-products-dataset">Kaggle</a> verfügbaren Kosmetikdatensatz, um den Index zu füllen, und um die Effizienz der Datenerfassung zu verbessern, verwendeten wir die Stapelverarbeitung. Während dieser Aufnahmephase werden wir die Einbettungen für das Feld "description" generieren und sie im neuen Feld "description_embeddings" indizieren.</p><p>Der gesamte Datenerfassungsprozess kann direkt über das im Repository verfügbare <strong>Jupyter Notebook</strong> verfolgt und ausgeführt werden. Das Notebook bietet eine Schritt-für-Schritt-Anleitung, wie die Daten gelesen, verarbeitet und in Elasticsearch indexiert werden, was eine einfache Reproduktion und das Experimentieren ermöglicht.</p><p>Sie können das Notebook unter folgendem Link aufrufen: <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/product-store-search/ingestion/ingestion.ipynb">Ingestion Notebook.</a></p><h2>Implementierung der Hybridsuche</h2><p>Implementieren wir nun die hybride Suche. Für die schlüsselwortbasierte Suche verwenden wir die Abfrage <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html">multi_match</a> , die auf die Felder "Name", "Kategorie" und "Beschreibung" abzielt. Dadurch wird sichergestellt, dass Dokumente abgerufen werden, die den Suchbegriff in einem dieser Felder enthalten.</p><p>Für die Vektorsuche verwenden wir die <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html">KNN-Abfrage</a>. Der Suchbegriff muss vor der Ausführung der Abfrage vektorisiert werden. Dies geschieht mithilfe der Methode, die den Eingabebegriff vektorisiert. Beachten Sie, dass für den Suchbegriff dasselbe Modell verwendet wird, das während der Datenaufnahme verwendet wurde.</p><p>Die Kombination beider Suchvorgänge erfolgt mithilfe des <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html">Reciprocal Rank Fusion (RRF) </a>-Algorithmus, der die Ergebnisse der beiden Abfragen zusammenführt und die Suchgenauigkeit durch Reduzierung von Rauschen erhöht. RRF ermöglicht die Kombination von schlüsselwortbasierter und Vektorsuche und verbessert so das Verständnis der Benutzeranfrage.</p>query = {
   "retriever": {
       "rrf": {
           "retrievers": [
               {
                   "standard": {
                       "query": organic_query['query']
                   }
               },
               {
                   "knn": {
                       "field": "description_embeddings",
                       "query_vector": vector,
                       "k": 5,
                       "num_candidates": 20
                   }
               }
           ],
           "rank_window_size": 20,
           "rank_constant": 5
       }
   },
   "_source": organic_query['_source']
}<h3>Ergebnisse im Vergleich: Stichwortsuche vs. Hybridsuche</h3><p>Vergleichen wir nun die Ergebnisse einer herkömmlichen Stichwortsuche mit denen einer Hybridsuche. Bei der Suche nach „Foundation für trockene Haut“ mittels Stichwortsuche erhalten wir folgende Ergebnisse:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcb5405df787bc8f5/6a17023e961e697ca1c4cdb4/52e717aa3c9c1fadfadb639f5fb77cf8e47e3b34-1600x1021.png" alt="Ergebnisse im Vergleich: Stichwortsuche vs. Hybridsuche" /><ol><li><p><strong>Revlon ColorStay Make-up für normale/trockene Haut</strong>: Revlon ColorStay Make-up bietet langanhaltende Deckkraft mit einer leichten Formel, die nicht verläuft, verblasst oder abfärbt. Mit Time-Release-Technologie ist diese ölfreie, feuchtigkeitsausgleichende Formel speziell für normale oder trockene Haut entwickelt, um kontinuierlich Feuchtigkeit zu spenden. Eigenschaften: Angenehmes Tragegefühl und bis zu 24 Stunden Halt. Mittlere bis hohe Deckkraft. Erhältlich in einer Reihe wunderschöner Farbtöne.
</p></li><li><p><strong>Maybelline Dream Smooth Mousse Foundation – Beschreibung</strong>: Warum Sie sie lieben werden: Die einzigartige, cremig-aufgeschlagene Foundation sorgt für ein 100 % babyweiches Hautgefühl.\n\nHaut Spendet 14 Stunden lang Feuchtigkeit – nie rau oder trocken. Die leichte Formel bietet optimale Feuchtigkeitspflege. Verschmilzt nahtlos mit der Haut und sorgt den ganzen Tag für ein frisches Gefühl. Ölfrei, parfümfrei, dermatologisch getestet, allergiegetestet, nicht komedogen – verstopft die Poren nicht. Sicher. Für empfindliche Haut.</p></li></ol><p><strong>Analyse</strong>: Bei der Suche nach „Foundation für trockene Haut“ wurden die Ergebnisse durch die exakte Übereinstimmung zwischen den Suchbegriffen und den Produkttiteln und -beschreibungen erzielt. Diese Übereinstimmung spiegelt jedoch nicht immer die beste Wahl wider. Zum Beispiel ist <strong>Revlon ColorStay Makeup für normale/trockene Haut</strong> eine gute Wahl, da es speziell für trockene Haut entwickelt wurde. Obwohl es ölfrei ist, ist seine Formel so konzipiert, dass sie für kontinuierliche Feuchtigkeitsversorgung sorgt. Im Gegensatz dazu erhielten wir auch <strong>die Maybelline Dream Smooth Mousse Foundation</strong>, die zwar ölfrei ist und Feuchtigkeit spendet, aber generell eher für fettige oder Mischhaut empfohlen wird, da ölfreie Produkte sich eher auf die Kontrolle des Öls konzentrieren, als die zusätzliche Feuchtigkeit zu spenden, die für trockene Haut notwendig ist. Dies verdeutlicht die Grenzen von schlüsselwortbasierten Suchen, die Produkte liefern können, die den spezifischen Bedürfnissen von Menschen mit trockener Haut nicht vollständig gerecht werden.</p><p>Wenn man nun dieselbe Suche mit dem hybriden Ansatz durchführt:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt412e38b327cf6a4f/6a17024066c4f94c52f8beb9/13b562a5120619355ba0861976102e208964a49f-1600x1021.png" alt="Durchführung der Suche mit dem hybriden Ansatz" /><ol><li><p><strong>CoverGirl Outlast Stay Luminous Foundation Creamy Natural (820): Beschreibung</strong>: Die CoverGirl Outlast Stay Luminous Foundation eignet sich perfekt, um ein taufrisches Finish und einen subtilen Glow zu erzielen. Es ist ölfrei und hat eine nicht fettende Formel, die Ihrer Haut einen natürlichen Glanz verleiht, der den ganzen Tag anhält! Diese Foundation hält den ganzen Tag, spendet der Haut Feuchtigkeit und sorgt gleichzeitig für eine makellose Deckkraft.

<strong>Analyse: </strong>Dieses Produkt passt gut, da es die Feuchtigkeitszufuhr betont, was für Anwender mit trockener Haut von entscheidender Bedeutung ist. Die Begriffe „spendet Feuchtigkeit“ und „glänzendes Finish“ entsprechen der Absicht des Nutzers, eine Foundation für trockene Haut zu finden. Die Vektorsuche hat wahrscheinlich das Konzept der Feuchtigkeitsversorgung verstanden und es mit dem Bedarf an einer Foundation in Verbindung gebracht, die trockene Haut berücksichtigt.
</p></li><li><p><strong>Revlon ColorStay Make-up für normale/trockene Haut: Beschreibung:</strong> Revlon ColorStay Make-up bietet langanhaltende Deckkraft mit einer leichten Formel, die nicht verklumpt, verblasst oder abfärbt. Dank der Time Release Technology ist diese ölfreie, feuchtigkeitsausgleichende Formel speziell für normale oder trockene Haut entwickelt worden, um kontinuierlich Feuchtigkeit zu spenden.

<strong>Analyse: </strong>Dieses Produkt geht direkt auf die Bedürfnisse von Anwendern mit trockener Haut ein, indem es ausdrücklich darauf hinweist, dass es für normale oder trockene Haut formuliert ist. Die „Feuchtigkeitsausgleichsformel“ und die kontinuierliche Feuchtigkeitszufuhr eignen sich hervorragend für alle, die eine Foundation suchen, die auf trockene Haut abgestimmt ist. Die Vektorsuche lieferte dieses Ergebnis erfolgreich, nicht nur aufgrund der Übereinstimmung mit den Schlüsselwörtern, sondern auch aufgrund des Fokus auf Feuchtigkeitsversorgung und der spezifischen Erwähnung von trockener Haut als Zielgruppe.
</p></li><li><p><strong>Serum Foundation – Beschreibung: </strong>Serum Foundations sind leichte Formulierungen mit mittlerer Deckkraft, die in einer umfassenden Farbpalette mit 21 Farbtönen erhältlich sind. Diese Foundations bieten eine moderate Deckkraft, die natürlich aussieht und sich wie ein sehr leichtes Serum anfühlt. Sie sind sehr niedrigviskos und werden mit der mitgelieferten Pumpe oder, falls gewünscht, mit der separat erhältlichen Glaspipette dosiert.

<strong>Analyse:</strong> In diesem Fall wird die leichte Serum-Foundation mit natürlichem Tragegefühl hervorgehoben, was den Bedürfnissen von Menschen mit trockener Haut entgegenkommt, da diese oft nach Produkten suchen, die sanft und feuchtigkeitsspendend sind und ein nicht maskenhaftes Finish bieten. Die Vektorsuche erfasste wahrscheinlich den breiteren Kontext der leichten, natürlichen Deckkraft und der serumartigen Textur, die mit Feuchtigkeitsspeicherung und einem angenehmen Auftragen verbunden ist, wodurch sie für trockene Haut relevant wird, obwohl der Begriff "trockene Haut" nicht explizit erwähnt wird.</p></li></ol><h2>Facettenimplementierung</h2><p>Facetten sind unerlässlich, um Suchergebnisse effizient zu verfeinern und zu filtern und den Nutzern eine gezieltere Navigation zu ermöglichen, insbesondere in Szenarien mit einer großen Produktvielfalt, wie beispielsweise im E-Commerce. Sie ermöglichen es den Nutzern, die Ergebnisse anhand von Attributen wie Kategorie, Marke oder Preis anzupassen, wodurch die Suche präziser wird. Zur Implementierung dieser Funktion verwenden wir <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html">Termaggregationen</a> auf den Feldern <code>category</code> und <code>brand</code> , die während der Indexerstellungsphase als <code>keyword</code> definiert wurden.</p>    query = build_query(term, categories, product_types, brands)
    query["aggs"] = {
        "product_types": {"terms": {"field": "product_type"}},
        "categories": {"terms": {"field": "category"}},
        "brands": {"terms": {"field": "brand.keyword"}}
    }<p>Den vollständigen Code für die Implementierung finden Sie <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/product-store-search/api/api.py#L144">hier</a>.</p><p>Nachfolgend die Facetten-Ergebnisse der Suche nach „Foundation für trockene Haut“:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt31080652a60d8600/6a1702416234e0af7ddb18e7/e8907af359c021eaa38ec7a6a53f10c325ee8ade-1146x1248.png" alt="Facet-Ergebnisse der Suche nach „Foundation für trockene Haut“" /><h2>Ergebnisse anpassen: Angeheftete Abfragen</h2><p>In einigen Fällen kann es von Vorteil sein, bestimmte Produkte in den Suchergebnissen hervorzuheben. Hierfür verwenden wir <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-pinned-query.html"><strong>angeheftete Suchanfragen</strong></a>, die es ermöglichen, dass bestimmte Produkte ganz oben in den Suchergebnissen erscheinen. Im Folgenden führen wir eine Suche nach dem Begriff „Foundation“ durch, ohne dabei Produkte zu bewerben:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt31e75c815262993e/6a170243509168ae42e1b95d/9396c4ed358e7a68eed47f17dd6915d0bad492aa-1600x1157.png" alt="Suchen Sie nach dem Begriff „Foundation“, ohne dabei Produkte zu bewerben." /><p>In unserem Beispiel können wir Produkte bewerben, die mit dem Etikett „Glutenfrei“ gekennzeichnet sind. Durch die Verwendung der Produkt-IDs stellen wir sicher, dass diese in den Suchergebnissen priorisiert werden. Konkret werden wir die folgenden Produkte bewerben: <strong>Serum Foundation</strong> (ID: 1043), <strong>Coverage Foundation</strong> (ID: 1042) und <strong>Realist Invisible Setting Powder</strong> (ID: 1039).</p>{
   "query":{
      "pinned":{
         "ids":[
            "1043",
            "1042",
            "1039"
         ],
         "organic":{
            "bool":{
               "must":[
                  {
                     "multi_match":{
                        "query":"foundation",
                        "fields":[
                           "name",
                           "category",
                           "description"
                        ]
                     }
                  }
               ]
            }
         }
      }
   }
}<p>Wir verwenden spezifische Produkt-IDs, um sicherzustellen, dass diese in den Suchergebnissen priorisiert werden. Die Abfragestruktur enthält eine Liste von Produkt-IDs, die oben "angeheftet" werden sollen (in diesem Fall die IDs 1043, 1042 und 1039), während die übrigen Ergebnisse dem organischen Suchverlauf folgen und eine Kombination von Bedingungen wie der Textabfrage in den Feldern "Name", "Kategorie" und "Beschreibung" verwenden. Auf diese Weise können Artikel gezielt beworben werden, wodurch ihre Sichtbarkeit gewährleistet wird, während die übrige Suche weiterhin auf der üblichen Relevanz basiert.</p><p>Nachfolgend sehen Sie das Ergebnis der Abfrageausführung mit den beworbenen Produkten:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt53a6d5cbef227f16/6a1702458b73cb68f0189ef3/8c1a547bfe31360c405eae0891c666635051a51b-1600x1039.png" alt="Ergebnis der Abfrageausführung mit den beworbenen Produkten" /><p>Den vollständigen Abfragecode finden Sie <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/product-store-search/api/api.py#L112">hier</a>.</p><h2>Analyse des Suchverhaltens mithilfe von Verhaltensanalysen</h2><p>Bis jetzt haben wir bereits Funktionen hinzugefügt, um die Relevanz der Suchergebnisse zu verbessern und die Auffindbarkeit von Produkten zu erleichtern. Nun vervollständigen wir unsere Suchlösung, indem wir eine Funktion integrieren, die uns hilft, das Suchverhalten der Nutzer zu analysieren und Muster wie Suchanfragen mit oder ohne Ergebnisse sowie Klicks auf Suchergebnisse zu identifizieren. Hierfür nutzen wir die <strong>Verhaltensanalysefunktion</strong> von Elastic. Damit können wir in nur wenigen Schritten das Suchverhalten der Nutzer überwachen und analysieren und so wertvolle Erkenntnisse gewinnen, um das Sucherlebnis zu optimieren.</p><h3>Erstellung der Verhaltensanalyse-Sammlung</h3><p>Unser erster Schritt wird darin bestehen, eine Sammlung zu erstellen, die für den Empfang aller Verhaltensanalyseereignisse zuständig sein wird. Um die Sammlung zu erstellen, greifen Sie über <strong>Suche &gt; Verhaltensanalysen</strong> auf die Kibana-Oberfläche zu. Im folgenden Beispiel haben wir die Sammlung mit dem Namen <code>tracking-search</code> erstellt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9b4cb5480ab0bfef/6a1702474a531b189936a7e7/c05e533212a3690c5ea9f2d5226cbcdc901c482a-1600x1009.png" alt="Verhaltensanalyse – Benennung Ihrer Sammlung" /><h3>Integration von Verhaltensanalysen in die Schnittstelle</h3><p>Unsere <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/hybrid-search-for-an-e-commerce-product-catalogue/app-product-store">Front-End</a> -Anwendung wurde in JavaScript entwickelt, und um Behavioral Analytics zu integrieren, werden wir die in der offiziellen Elastic-Dokumentation beschriebenen Schritte zur Installation des <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/behavioral-analytics-start.html#behavioral-analytics-start-ui-integration-js-client"><strong>Behavioral Analytics JavaScript Trackers</strong></a> befolgen.</p><h3>Implementierung des JavaScript-Trackers</h3><p>Nun importieren wir den Tracker-Client in unsere Anwendung und verwenden die Methoden <code>trackPageView</code>, <code>trackSearch</code> und <code>trackSearchClick</code> , um Benutzerinteraktionen zu erfassen.</p><p><strong>Hinweis</strong>: Obwohl wir ein Tool zur Erfassung von Nutzerinteraktionsdaten verwenden, ist die Einhaltung der <strong>DSGVO</strong> unerlässlich. Dies bedeutet, die Nutzer klar darüber zu informieren, welche Daten erhoben werden, wie diese verwendet werden und ihnen die Möglichkeit zu geben, der Nachverfolgung zu widersprechen. Darüber hinaus müssen wir strenge Sicherheitsmaßnahmen implementieren, um die gesammelten Informationen zu schützen und die Rechte der Nutzer, wie z. B. das Recht auf Datenzugriff und -löschung, zu respektieren und sicherzustellen, dass alle Schritte den Grundsätzen der DSGVO entsprechen.
</p><p><strong>Schritt 1: Erstellen der Tracker-Instanz</strong></p><p>Zuerst erstellen wir die Tracker-Instanz, die die Interaktionen überwacht. In dieser Konfiguration definieren wir den Zielendpunkt, den Sammlungsnamen und den API-Schlüssel:</p>createTracker({
  endpoint: "https://endpoint:443",
  collectionName: "tracking-search",
  apiKey: "api-key"
});<p><strong>Schritt 2: Seitenaufrufe erfassen</strong></p><p>Um Seitenaufrufe zu verfolgen, können wir das <code>trackPageView</code> -Ereignis konfigurieren:</p>    trackPageView({
      page: {
        title: "home-page"
      },
    });<p>Weitere Einzelheiten zum <code>trackPageView</code> -Ereignis finden Sie in dieser <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/behavioral-analytics-event-reference.html#behavioral-analytics-event-reference-pageview-fields">Dokumentation</a>.</p><p><strong>Schritt 3: Suchanfragen erfassen</strong></p><p>Um die Suchaktionen der Nutzer zu überwachen, verwenden wir die <code>trackSearch</code> -Methode:</p>      trackSearch({
        search: {
          query: searchTerm,
          results: {
            items: documents,
            total_results: response.data.length,
          },
        },
      });<p>Hier erfassen wir den Suchbegriff und die Suchergebnisse.</p><p><strong>Schritt 4: Klicks auf Suchergebnisse verfolgen</strong></p><p>Um schließlich Klicks auf Suchergebnisse zu erfassen, verwenden wir die <code>trackSearchClick</code> -Methode:</p>trackSearchClick({
      document: { id: product.id, index: "products-catalog"},
      search: {
        query: searchTerm,
        page: {
          current: 1,
          size: products.length,
        },
        results: {
          items: documents,
          total_results: products.length,
        },
        search_application: "app-product-store"
      },
    });<p>Wir erfassen Informationen über die ID des angeklickten Dokuments sowie über den Suchbegriff und die Suchergebnisse.</p><h3>Analyse der Daten in Kibana</h3><p>Da nun Benutzerinteraktionsereignisse erfasst werden, können wir wertvolle Daten über Suchaktionen gewinnen. Kibana verwendet das Tool „Verhaltensanalyse“, um diese Verhaltensdaten zu visualisieren und zu analysieren. Um die Ergebnisse anzuzeigen, navigieren Sie einfach zu <strong>„Suchen“ &gt; „Verhaltensanalyse“ &gt; „Meine Sammlung“</strong>. Dort wird eine Übersicht der erfassten Ereignisse angezeigt.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdab4f4507c5a4732/6a17024860084b34ca3c4411/e219c4af2e01b0ccc1b9079459a07832835abc75-1600x1155.png" alt="Datenanalyse in Kibana" /><p>In dieser Übersicht erhalten wir einen allgemeinen Überblick über die Ereignisse, die für jede in unsere Benutzeroberfläche integrierte Aktion erfasst werden. Aus diesen Informationen können wir wertvolle Einblicke in das Suchverhalten der Nutzer gewinnen. Wenn Sie jedoch personalisierte Dashboards mit Kennzahlen erstellen möchten, die besser zu Ihrem spezifischen Szenario passen, bietet Kibana leistungsstarke Tools zum Erstellen von Dashboards, mit denen Sie verschiedene Visualisierungen Ihrer Kennzahlen erstellen können.</p><p>Im Folgenden habe ich einige Visualisierungen und Diagramme erstellt, um beispielsweise die am häufigsten gesuchten Begriffe im Zeitverlauf, Suchanfragen ohne Ergebnisse, eine Wortwolke mit den am häufigsten gesuchten Begriffen und schließlich eine geografische Visualisierung zur Ermittlung der Herkunft der Suchzugriffe zu überwachen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt04ced4406436f942/6a17024a5091685116e1b961/84a2c39dab77a3f9366c258a3a45d2cbc7df125e-1600x689.png" alt="Visualisierungen und Diagramme zur Überwachung" /><h2>Fazit</h2><p>In diesem Artikel haben wir eine hybride Suchlösung vorgestellt, die Keyword- und Vektorsuche kombiniert und so genauere und relevantere Ergebnisse für die Nutzer liefert. Wir haben auch untersucht, wie man zusätzliche Funktionen wie Facetten und die Personalisierung der Ergebnisse mit angehefteten Suchanfragen nutzen kann, um ein umfassenderes und effizienteres Sucherlebnis zu schaffen.</p><p>Darüber hinaus haben wir <strong>die Verhaltensanalyse</strong> von Elastic integriert, um das Nutzerverhalten während der Interaktion mit der Suchmaschine zu erfassen und zu analysieren. Mithilfe von Methoden wie <code>trackPageView</code>, <code>trackSearch</code> und <code>trackSearchClick</code> konnten wir Suchanfragen, Klicks auf Suchergebnisse und Seitenaufrufe überwachen und so wertvolle Einblicke in das Suchverhalten gewinnen.</p><h2>Referenzen</h2><p>Datensatz</p><p><a href="https://www.kaggle.com/datasets/shivd24coder/cosmetic-brand-products-dataset">https://www.kaggle.com/datasets/shivd24coder/cosmetic-brand-products-dataset</a></p><p>Transformator</p><p><a href="https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2">https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2</a></p><p>Reziproke Rangfusion</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/retriever.html#rrf-retriever">https://www.elastic.co/guide/en/elasticsearch/reference/current/retriever.html#rrf-retriever</a></p><p>Knn-Abfrage</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html</a></p><p>Angeheftete Anfrage</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-pinned-query.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-pinned-query.html</a></p><p>APIs für Verhaltensanalysen</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/behavioral-analytics-apis.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/behavioral-analytics-apis.html</a></p><p>https://www.elastic.co/guide/en/elasticsearch/reference/current/behavioral-analytics-overview.html</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/hybrid-search-ecommerce</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/hybrid-search-ecommerce</guid>
    <category><![CDATA[Vektordatenbank]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63c711d1bf9b2501/6a17024c66c4f9c2b7f8bebd/05578fc595a12f6b1ebf88a10a2a31e9971b545e-1200x628.png" length="0" type="image/png"/>
    <pubDate>Tue, 12 Nov 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Implementierung der semantischen Suche: Erstellen einer Rezeptsuche mit Elasticsearch]]></title>
    <description><![CDATA[Implementierung der semantischen Suche im Kontext von E-Commerce-Websites.]]></description>
    <content:encoded><![CDATA[<h2>Einleitung</h2><p>Viele E-Commerce-Websites sind daran interessiert, das Sucherlebnis für Rezepte zu verbessern. Die semantische Suche ermöglicht es Kunden bei korrekter Anwendung, die benötigten Zutaten schnell anhand natürlicher Suchanfragen zu finden, wie zum Beispiel „etwas für den Valentinstag“ oder „Thanksgiving-Gerichte“.</p><p>In diesem Artikel zeigen wir, wie man Elasticsearch zur Implementierung einer semantischen Suche nutzt, die solche Anfragen unterstützt. Wir werden einen Index konfigurieren, um den Katalog der Zutaten und Produkte eines Supermarkts zu speichern, und demonstrieren, wie dieser Index zur Verbesserung der Rezeptsuche verwendet werden kann. Im Verlauf des Artikels erklären wir, wie diese Datenstruktur erstellt wird und wie Techniken der natürlichen Sprachverarbeitung angewendet werden, um relevante Ergebnisse zu liefern, die der Absicht des Kunden entsprechen.</p><p>Der gesamte in diesem Artikel vorgestellte Code wurde in Python entwickelt und ist auf <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/building-a-recipe-search-with-elasticsearch">GitHub</a> verfügbar. Sie können auf das Repository zugreifen, um den Quellcode einzusehen, gegebenenfalls Anpassungen vorzunehmen und die Lösungen direkt in Ihrer Entwicklungsumgebung zu implementieren.</p><h2>Beginn der Implementierung der semantischen Suche</h2><p>Um mit der Implementierung der semantischen Suche zu beginnen, müssen wir zunächst das natürliche Sprachmodell definieren. Elastic bietet sein eigenes Modell <a href="https://www.elastic.co/guide/en/machine-learning/8.15/ml-nlp-elser.html"><strong>ELSER</strong></a> an, unterstützt aber auch die Integration von NLP-Modellen verschiedener Anbieter, wie beispielsweise Hugging Face. Diese Flexibilität ermöglicht es Ihnen, die Option zu wählen, die Ihren Bedürfnissen am besten entspricht.</p><p>In diesem Artikel verwenden wir <strong>ELSER</strong>, das die Komplexität der Bereitstellung und Verwaltung von NLP-Modellen reduziert. Darüber hinaus bietet Elastic die Funktion <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html"><strong>semantic_text</strong></a> an, die den Prozess erheblich vereinfacht. Mit <strong>semantic_text</strong> wird der gesamte Einbettungsgenerierungsprozess unkompliziert und automatisiert. Sie müssen lediglich einen Inferenzpunkt definieren und das Feld angeben, das die Einbettungen in Ihrer Indexzuordnung aufnehmen soll. Während der Dokumentenindizierung werden Einbettungen generiert und automatisch dem angegebenen Feld zugeordnet.</p><h3>Einrichtungsschritte</h3><p>Nachfolgend sind die Schritte zum Erstellen eines Index mit semantischer Suchunterstützung aufgeführt. Wenn Sie diese Anweisungen befolgen, wird Ihr Index konfiguriert und ist bereit für semantische Suchen:</p><ol><li><p><strong>Erstelle den </strong><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html"><strong>Inferenzpunkt</strong></a>.</p></li><li><p><a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/infra.py"><strong>Erstellen Sie den Index</strong></a> und setzen Sie das Beschreibungsfeld auf semantic_text, damit er die Einbettungen empfangen kann.</p></li><li><p><a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/ingestion.py"><strong>Die Daten werden im Lebensmittelkatalogindex indexiert</strong></a> , der einen Produktkatalog speichert. Dieser Katalog wurde aus einem <a href="https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv">hier</a> verfügbaren Datensatz erstellt.</p></li></ol><h2>Anwendung der semantischen Suche in Supermärkten</h2><p>Nachdem wir den Index nun mit Produktdaten aus Lebensmittelgeschäften gefüllt haben, testen und validieren wir Suchanfragen, um die Suchergebnisse mithilfe der semantischen Suche zu verbessern. Unser Ziel ist es, ein intelligenteres Sucherlebnis zu bieten, das den Kontext und die Absicht des Nutzers versteht und relevantere und genauere Ergebnisse liefert.</p><h3>Durch semantische Suche gelöste Herausforderungen</h3><p>Anhand des Produktkatalogs wollen wir untersuchen, wie die semantische Suche das Sucherlebnis in Supermärkten verändern kann, indem sie Vokabel- und Kontextprobleme angeht, mit denen die traditionelle lexikalische Suche oft zu kämpfen hat.</p><h4><strong>1. Interpretation kulinarischer Absichten</strong></h4><p><strong>Problem 01</strong>: Ein Kunde sucht möglicherweise nach „Meeresfrüchte zum Grillen“, aber ein lexikalisches Suchsystem versteht die Absicht hinter der Suchanfrage möglicherweise nicht vollständig. Es kann vorkommen, dass nicht alle zum Grillen geeigneten Meeresfrüchteprodukte erkannt werden und nur diejenigen zurückgegeben werden, die den genauen Begriff „Meeresfrüchte“ oder „Grill“ im Produktnamen enthalten.</p><p>Zunächst führen wir eine lexikalische Suche durch und analysieren die Ergebnisse. Anschließend werden wir das Gleiche mit einer semantischen Suche durchführen und die Ergebnisse für denselben Suchbegriff vergleichen.</p><p><strong>lexikalische Abfrage</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "seafood for grilling",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>Ergebnisse:</strong></p><p>Suchtyp</p><p>Name</p><p>Punktzahl</p><p>Lexikalisch</p><p>Nordwestfisch Alaskan Bairdi Schneekrabbe</p><p>10,453125</p><p>Lexikalisch</p><p>Herr Yoshidas, Sauce Original Gourmet</p><p>7,2289705</p><p>Lexikalisch</p><p>Premium-Meeresfrüchte-Probierpaket – 20 Stück</p><p>7.1924105</p><p>Lexikalisch</p><p>Amerikanischer Roter Schnapper - Ganz, mit Kopf, ausgenommen</p><p>6,998647</p><p>Lexikalisch</p><p>Hummerscheren und -arme, nachhaltig wild gefangen</p><p>6,438654</p><p>Die lexikalische Suche ergab einige Meeresfrüchte, die sich zum Grillen eignen, wie zum Beispiel Amerikanischer Roter Schnapper und Nordwestfisch Alaskan Bairdi Schneekrabbe. Die lexikalische Suche lieferte jedoch weniger relevante Produkte an die Spitze der Liste, wie zum Beispiel die Mr. Yoshida Sauce, die keine Meeresfrüchte-, sondern eine Fleischsauce ist. Dies lässt darauf schließen, dass der lexikalische Algorithmus Schwierigkeiten hatte, den Kontext von „zum Grillen“ vollständig zu verstehen.</p><p><strong>Lösung für semantische Suche</strong></p><p>Wir verwenden eine Abfrage, die den Begriff „Meeresfrüchte“ mit Zubereitungskontexten wie „Grillen“ kombiniert, um eine umfassende Liste von Optionen zurückzugeben, wie zum Beispiel Fischfilets, Garnelen und Jakobsmuscheln, die sich ideal zum Grillen eignen – selbst wenn die Wörter „Grill“ oder „Meeresfrüchte“ nicht direkt im Produktnamen vorkommen. Dadurch wird sichergestellt, dass die Suchergebnisse besser mit den Absichten des Kunden übereinstimmen.</p><p><strong>semantische Suche:</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "seafood for grilling"

       }
   })<p>Suchtyp</p><p>Name</p><p>Punktzahl</p><p>Semantisch</p><p>Ganzer, ausgenommener Wolfsbarsch mit Kopf</p><p>16.175909</p><p>Semantisch</p><p>Alaska-Schwarzkabeljau (Sablefisch)</p><p>15,855331</p><p>Semantisch</p><p>Amerikanischer Roter Schnapper - Ganz, mit Kopf</p><p>15,454779</p><p>Semantisch</p><p>Nordwestfisch Alaskan Bairdi Schneekrabbe</p><p>15,855331</p><p>Semantisch</p><p>Amerikanischer Roter Schnapper - Ganz, mit Kopf</p><p>15,3892355</p><p>Die semantische Suche lieferte nicht nur Produkte, die direkt mit dem Begriff „Meeresfrüchte“ in Verbindung standen, sondern verstand auch den Kontext von „Grillen“ und brachte ganze Fische und Filets zum Vorschein, die zum Grillen geeignet sind. Entscheidend ist hierbei die Präzision der Ergebnisse, die auch ganze Fischsorten wie Branzino und Alaska Black Cod umfassten, die beide häufig zum Grillen verwendet werden.</p><p><strong>Problem 02 </strong>: Viele Kunden suchen nach schnellen und einfachen Abendessenlösungen nach einem langen Arbeitstag und verwenden dabei Begriffe wie „einfache Abendessen für die Woche“. Die traditionelle lexikalische Suche erfasst das Konzept der Schnellgerichte möglicherweise nicht vollständig, da sie sich oft nur auf Produkte konzentriert, die das Wort „einfach“ in ihrem Namen enthalten.</p><p>Wie schon in der vorherigen Aufgabe beginnen wir mit einer lexikalischen Suche. Anschließend werden wir eine Lösung mittels semantischer Suche anwenden.</p><p><strong>lexikalische Abfrage</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,   
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "easy weeknight meals",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>Ergebnisse:</strong></p><p>Suchtyp</p><p>Name</p><p>Punktzahl</p><p>Lexikalisch</p><p>Avery Easy Peel Adressetiketten, 4200 Stück</p><p>8,017723</p><p>Lexikalisch</p><p>Omeals Selbsterhitzende Not-/Portable Mahlzeiten 32</p><p>6,592727</p><p>Lexikalisch</p><p>Poke-Brot mit Gelbflossenthunfischwürfeln</p><p>5,836883</p><p>Lexikalisch</p><p>Hefty Super Weight 12 oz Schaumstoff</p><p>5,8116536</p><p>Lexikalisch</p><p>Vanity Fair Alltagsservietten, 2-lagig, 110 Stück</p><p>5,752989</p><p>Die lexikalische Suche lieferte deutlich weniger relevante Ergebnisse, darunter Artikel, die in keinem Zusammenhang mit Mahlzeiten stehen, wie zum Beispiel Avery Easy Peel Adressetiketten und Vanity Fair Everyday Servietten. Diese Produkte erfüllen nicht das Bedürfnis des Nutzers nach schnellen Mahlzeiten. Während die lexikalische Suche ein nützliches Produkt (Omeals Selbstheizende Notfallmahlzeiten) lieferte, enthielten andere Ergebnisse, wie Servietten und Etiketten, in ihren Beschreibungen lediglich die Wörter „einfach“ oder „Wochentag“, ohne wirklich auf die Absicht des Nutzers nach einer schnellen Mahlzeitenlösung einzugehen.</p><p><strong>Lösung für semantische Suche</strong></p><p>Wir haben eine Abfrage implementiert, die die Absicht hinter schnellen und einfachen Mahlzeiten versteht. Es assoziiert Produkte, die schnell zubereitet werden können, wie vorgekochtes Fleisch, Tiefkühlnudeln oder Fertiggerichte, auch wenn sie das Wort „einfach“ nicht explizit im Namen tragen. Dieser Ansatz stellt sicher, dass die Kunden die am besten geeigneten Optionen für ein schnelles Abendessen unter der Woche finden und somit dem Bedürfnis nach Bequemlichkeit gerecht werden.</p><p><strong>semantische Suche</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "easy weeknight meals"

       }
   })<p><strong>Ergebnisse:</strong></p><p>Suchtyp</p><p>Name</p><p>Punktzahl</p><p>Semantisch</p><p>Omeals Selbsterhitzende Not-/Portable Mahlzeiten 32</p><p>14.610006</p><p>Semantisch</p><p>Nissin, Cup Noodles, Garnelen, 71 g</p><p>13,751424</p><p>Semantisch</p><p>Namaste Glutenfreie Waffel- und Pfannkuchenmischung</p><p>13,73376</p><p>Semantisch</p><p>Idaho-Kartoffeln, Golden Grill Hashbrown-Kartoffeln</p><p>12,549422</p><p>Semantisch</p><p>Nissin Cup Noodles, Hühnchen, 24er-Packung</p><p>12.034527</p><p>Die semantische Suche ergab Produkte, die eindeutig mit schnellen und praktischen Mahlzeiten in Verbindung stehen, wie zum Beispiel Instantnudeln (Cup Noodles), vorgekochte Kartoffeln und Pfannkuchenmischungen, die typische Optionen für ein einfaches Abendessen unter der Woche sind. Dies beweist, dass die semantische Suche das Konzept hinter dem Ausdruck „einfache Gerichte für die Woche“ erfassen kann und die Absicht des Nutzers erkennt, schnelle und bequeme Mahlzeiten zu finden. Interessanterweise können auch Produkte aus anderen Kategorien, wie zum Beispiel „Limonade“, einbezogen werden, wenn dies im Kontext relevant ist (z. B. Getränke zu Mahlzeiten).</p><h4><strong>2. Regionale Begriffe und Vokabelvariationen</strong></h4><p><strong>Problem</strong>: Ein Kunde sucht möglicherweise nach „Soda“, während ein anderer Kunde für dasselbe Produkt „Pop“ verwendet. Die traditionelle lexikalische Suche erkennt nicht, dass sich beide Begriffe auf denselben Gegenstand beziehen.</p><p><strong>lexikalische Abfrage</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "refreshing pop drink low sugar",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>Ergebnisse:</strong></p><p>Suchtyp</p><p>Name</p><p>Punktzahl</p><p>Lexikalisch</p><p>Prime Hydration+ Sticks Elektrolyt-Getränkemischung</p><p>14,492869</p><p>Lexikalisch</p><p>Capri Sun, 100 % Saft, Probierpackung</p><p>12.340851</p><p>Lexikalisch</p><p>Joyburst Energy Drink, Frose Rose, 12</p><p>11,839179</p><p>Lexikalisch</p><p>Kellogg's Pop-Tarts, Zuckerguss-Zimt</p><p>9,97788</p><p>Lexikalisch</p><p>Kind Mini-Riegel, Probierpackung, 0,7</p><p>9,336912</p><p>Die lexikalische Suche konzentriert sich auf exakte Wortübereinstimmungen. Während Produkte wie Prime Hydration und Capri Sun zurückgegeben wurden, führte die direkte Übereinstimmung mit dem Begriff „Pop“ auch zu irrelevanten Ergebnissen, wie zum Beispiel Kellogg's Pop-Tarts, das ein Snack und kein Getränk ist. Dies verdeutlicht, wie die lexikalische Suche weniger effektiv sein kann, wenn ein Begriff mehrere Bedeutungen hat oder mehrdeutig sein kann.</p><p><strong>Lösung für semantische Suche</strong></p><p>Bei semantischen Anfragen können wir das Problem der Vokabelvariationen überwinden, das bei der lexikalischen Suche nicht gelöst werden kann. Durch die Erweiterung der Suchbegriffe können wir Ergebnisse erzielen, die auf dem Kontext basieren und relevantere und umfassendere Antworten liefern.</p><p><strong>Abfrage:</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "refreshing pop drink low sugar"

       }
   })<p><strong>Ergebnisse:</strong></p><p>Suchtyp</p><p>Name</p><p>Punktzahl</p><p>Semantisch</p><p>Olipop 12 oz Präbiotika-Limonade (verschiedene Sorten)</p><p>14,776867</p><p>Semantisch</p><p>Bai Antioxidant Cocofusion, Probierpackung, 18</p><p>14,663253</p><p>Semantisch</p><p>Monster Energy Drink, Zero Ultra, 24</p><p>14,486348</p><p>Semantisch</p><p>Joyburst Energy Variety, 355 ml</p><p>14.007214</p><p>Semantisch</p><p>Joyburst Energy Drink, Frose Rose, 12</p><p>13,641038</p><p>Die semantische Suche liefert Produkte, die direkt dem Konzept von „Pop“ als Synonym für „Soda“ entsprechen (wie z. B. Olipop Prebiotics Soda), auch wenn der genaue Begriff „Pop“ nicht im Produktnamen enthalten ist. Die Suche erkannte die Absicht des Nutzers – ein erfrischendes Getränk mit wenig Zucker – und konnte relevante Produkte zurückgeben, darunter Optionen wie präbiotische Limonaden (Olipop) und zuckerfreie Energy-Drinks (Monster Energy Drink).</p><h2>Fazit</h2><p>Die Implementierung der semantischen Suche im Kontext von Lebensmittelgeschäften hat sich als äußerst effektiv erwiesen, um komplexe Anfragen wie „Meeresfrüchte zum Grillen“ und „einfache Gerichte für die Woche“ zu verstehen. Dieser Ansatz ermöglichte es uns, die Absicht der Nutzer genauer zu interpretieren und ihnen hochrelevante Produkte zurückzugeben.</p><p>Durch den Einsatz von Elasticsearch und die Vereinfachung des Prozesses mit ELSER konnten wir die semantische Suche schnell und effizient implementieren, die Suchergebnisse deutlich verbessern und ein agileres und zielgerichteteres Einkaufserlebnis ermöglichen. Dadurch wurde nicht nur der Suchprozess optimiert, sondern auch die Relevanz der den Kunden angebotenen Ergebnisse erhöht.</p><h2>Referenzen</h2><p>Modell ELSER:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html</a></p><p></p><p>Semantischer Text:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html</a></p><p></p><p>Datensatz:</p><p><a href="https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv">https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv</a></p><p></p><p>Semantische Suche:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/semantic-search-elasticsearch-ecommerce</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/semantic-search-elasticsearch-ecommerce</guid>
    <category><![CDATA[Grundlagen]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c545fc80b6d79d6/6a170214839dfad776dcfd6f/d968e646240cd3ef7c79b5124d562a5f951d812b-1440x840.png" length="0" type="image/png"/>
    <pubDate>Thu, 07 Nov 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>