Elasticsearch ist eine verteilte -basierte Open-Source-Such- und Analyse-Engine, die auf Apache Lucene basiert und schnelle Suchfunktionen in Echtzeit bietet. Es handelt sich um einen NoSQL-Datenspeicher, der standardmäßig dokumentenorientiert, skalierbar und schemalos ist. Elasticsearch ist für die skalierbare Arbeit mit großen Datenmengen konzipiert. Als Suchmaschine bietet sie schnelle Indexierungs- und Suchfunktionen, die horizontal über mehrere Knoten hinweg skaliert werden können. JSON Schamloser Plug: ist eine Echtzeit-Indexierungsdatenbank in der Cloud. Es erstellt automatisch Indizes, die nicht nur für die Suche, sondern auch für Aggregationen und Verknüpfungen optimiert sind, sodass Ihre Anwendungen Daten schnell und einfach abfragen können, unabhängig davon, woher sie kommen und in welchem Format sie vorliegen. In diesem Beitrag geht es jedoch darum, einige Problemumgehungen hervorzuheben , falls Sie wirklich Verknüpfungen im SQL-Stil in Elasticsearch durchführen möchten. Rockset Warum sind Datenbeziehungen wichtig? Wir leben in einer stark vernetzten Welt, in der der Umgang mit Datenbeziehungen wichtig ist. Relationale Datenbanken eignen sich gut für den Umgang mit Beziehungen, aber angesichts der sich ständig ändernden Geschäftsanforderungen führt das feste Schema dieser Datenbanken zu Skalierbarkeits- und Leistungsproblemen. Der Einsatz von NoSQL-Datenspeichern erfreut sich immer größerer Beliebtheit, da sie mehrere Herausforderungen im Zusammenhang mit herkömmlichen Datenverarbeitungsansätzen bewältigen können. Unternehmen haben ständig mit komplexen Datenstrukturen zu kämpfen, bei denen zur Analyse der Daten Aggregationen, Zusammenführungen und Filterfunktionen erforderlich sind. Mit der explosionsartigen Zunahme unstrukturierter Daten gibt es eine wachsende Zahl von Anwendungsfällen, die die Zusammenführung von Daten aus verschiedenen Quellen für Datenanalysezwecke erfordern. Während Joins in erster Linie ein SQL-Konzept sind, sind sie auch in der NoSQL-Welt gleichermaßen wichtig. Joins im SQL-Stil werden in Elasticsearch nicht als erstklassige Bürger unterstützt. In diesem Artikel wird erläutert, wie Beziehungen in Elasticsearch mithilfe verschiedener Techniken definiert werden, z. B. Denormalisierung, anwendungsseitige Verknüpfungen, verschachtelte Dokumente und Eltern-Kind-Beziehungen. Außerdem werden die Anwendungsfälle und Herausforderungen untersucht, die mit jedem Ansatz verbunden sind. Umgang mit Beziehungen in Elasticsearch Da es sich bei Elasticsearch nicht um eine relationale Datenbank handelt, gibt es Verknüpfungen nicht als native Funktionalität wie in einer SQL-Datenbank. Der Schwerpunkt liegt mehr auf der Sucheffizienz als auf der Speichereffizienz. Die gespeicherten Daten werden praktisch abgeflacht oder denormalisiert, um schnelle Suchanwendungsfälle zu ermöglichen. Es gibt mehrere Möglichkeiten, Beziehungen in Elasticsearch zu definieren. Basierend auf Ihrem Anwendungsfall können Sie in Elasticsearch eine der folgenden Techniken auswählen, um Ihre Daten zu modellieren: Eins-zu-eins-Beziehungen: Objektzuordnung Eins-zu-viele-Beziehungen: Verschachtelte Dokumente und das Eltern-Kind-Modell Viele-zu-viele-Beziehungen: Denormalisierung und anwendungsseitige Verknüpfungen Eins-zu-eins-Objektzuordnungen sind einfach und werden hier nicht ausführlich besprochen. Im weiteren Verlauf dieses Blogs werden die beiden anderen Szenarien ausführlicher behandelt. Verwalten Sie Ihr Datenmodell in Elasticsearch Es gibt vier gängige Ansätze zur Datenverwaltung in Elasticsearch: Denormalisierung Anwendungsseitige Verknüpfungen Verschachtelte Objekte Eltern-Kind-Beziehungen Denormalisierung Die Denormalisierung bietet die beste Leistung bei der Abfragesuche in Elasticsearch, da das Zusammenführen von Datensätzen zum Zeitpunkt der Abfrage nicht erforderlich ist. Jedes Dokument ist unabhängig und enthält alle erforderlichen Daten, sodass keine teuren Verknüpfungsvorgänge erforderlich sind. Bei der Denormalisierung werden die Daten zum Zeitpunkt der Indizierung in einer abgeflachten Struktur gespeichert. Dies erhöht jedoch die Dokumentgröße und führt zur Speicherung doppelter Daten in jedem Dokument. Speicherplatz ist kein teures Gut und gibt daher wenig Anlass zur Sorge. Anwendungsfälle für die Denormalisierung Bei der Arbeit mit verteilten Systemen kann die Zusammenführung von Datensätzen über das Netzwerk zu erheblichen Latenzen führen. Sie können diese teuren Join-Vorgänge vermeiden, indem Sie Daten denormalisieren. Viele-zu-viele-Beziehungen können durch Datenreduzierung gehandhabt werden. Herausforderungen bei der Datendenormalisierung Das Duplizieren von Daten in vereinfachte Dokumente erfordert zusätzlichen Speicherplatz. Die Verwaltung von Daten in einer abgeflachten Struktur verursacht zusätzlichen Aufwand für Datensätze, die relationaler Natur sind. Aus Programmiersicht erfordert die Denormalisierung zusätzlichen technischen Aufwand. Sie müssen zusätzlichen Code schreiben, um die in mehreren relationalen Tabellen gespeicherten Daten zu reduzieren und sie einem einzelnen Objekt in Elasticsearch zuzuordnen. Die Denormalisierung von Daten ist keine gute Idee, wenn sich Ihre Daten häufig ändern. In solchen Fällen würde die Denormalisierung eine Aktualisierung aller Dokumente erfordern, wenn sich eine Teilmenge der Daten ändern würde, und sollte daher vermieden werden. Bei abgeflachten Datensätzen dauert der Indizierungsvorgang länger, da mehr Daten indiziert werden. Wenn sich Ihre Daten häufig ändern, deutet dies darauf hin, dass Ihre Indizierungsrate höher ist, was zu Problemen bei der Clusterleistung führen kann. Anwendungsseitige Verknüpfungen Anwendungsseitige Verknüpfungen können verwendet werden, wenn die Beziehung zwischen Dokumenten aufrechterhalten werden muss. Die Daten werden in separaten Indizes gespeichert und Join-Vorgänge können während der Abfragezeit von der Anwendungsseite aus durchgeführt werden. Dies erfordert jedoch das Ausführen zusätzlicher Abfragen zum Zeitpunkt der Suche in Ihrer Anwendung, um Dokumente zu verbinden. Anwendungsfälle für anwendungsseitige Verknüpfungen Anwendungsseitige Verknüpfungen stellen sicher, dass die Daten normalisiert bleiben. Änderungen werden an einem Ort vorgenommen und Sie müssen Ihre Dokumente nicht ständig aktualisieren. Durch diesen Ansatz wird die Datenredundanz minimiert. Diese Methode funktioniert gut, wenn weniger Dokumente vorhanden sind und Datenänderungen weniger häufig sind. Herausforderungen bei anwendungsseitigen Verknüpfungen Die Anwendung muss zum Zeitpunkt der Suche mehrere Abfragen ausführen, um Dokumente zusammenzuführen. Wenn der Datensatz viele Verbraucher hat, müssen Sie denselben Abfragesatz mehrmals ausführen, was zu Leistungsproblemen führen kann. Dieser Ansatz nutzt daher nicht die wahre Leistungsfähigkeit von Elasticsearch. Dieser Ansatz führt zu Komplexität auf der Implementierungsebene. Es erfordert das Schreiben von zusätzlichem Code auf Anwendungsebene, um Verknüpfungsvorgänge zu implementieren und eine Beziehung zwischen Dokumenten herzustellen. Verschachtelte Objekte Der verschachtelte Ansatz kann verwendet werden, wenn Sie die Beziehung jedes Objekts im Array beibehalten müssen. Verschachtelte Dokumente werden intern als separate Lucene-Dokumente gespeichert und können zum Zeitpunkt der Abfrage zusammengefügt werden. Es handelt sich um Index-Time-Joins, bei denen mehrere Lucene-Dokumente in einem einzigen Block gespeichert werden. Aus Anwendungssicht sieht der Block wie ein einzelnes Elasticsearch-Dokument aus. Die Abfrage erfolgt daher relativ schneller, da sich alle Daten im selben Objekt befinden. Verschachtelte Dokumente befassen sich mit Eins-zu-Viele-Beziehungen. Anwendungsfälle für verschachtelte Dokumente Das Erstellen verschachtelter Dokumente wird bevorzugt, wenn Ihre Dokumente Arrays von Objekten enthalten. Abbildung 1 unten zeigt, wie der verschachtelte Typ in Elasticsearch die interne Indizierung von Arrays von Objekten als separate Lucene-Dokumente ermöglicht. Lucene hat kein Konzept für innere Objekte, daher ist es interessant zu sehen, wie Elasticsearch das Originaldokument intern in abgeflachte mehrwertige Felder umwandelt. Ein Vorteil der Verwendung verschachtelter Abfragen besteht darin, dass keine objektübergreifenden Übereinstimmungen durchgeführt werden und somit unerwartete Übereinstimmungsergebnisse vermieden werden. Es erkennt Objektgrenzen und macht die Suche präziser. Abbildung 1: Arrays von Objekten, die intern als separate Lucene-Dokumente in Elasticsearch unter Verwendung eines verschachtelten Ansatzes indiziert werden Herausforderungen mit verschachtelten Objekten Das Stammobjekt und seine verschachtelten Objekte müssen vollständig neu indiziert werden, um ein verschachteltes Objekt hinzuzufügen/aktualisieren/löschen zu können. Mit anderen Worten: Eine Aktualisierung eines untergeordneten Datensatzes führt zu einer Neuindizierung des gesamten Dokuments. Auf verschachtelte Dokumente kann nicht direkt zugegriffen werden. Auf sie kann nur über das zugehörige Stammdokument zugegriffen werden. Suchanfragen geben das gesamte Dokument zurück, anstatt nur die verschachtelten Dokumente zurückzugeben, die der Suchabfrage entsprechen. Wenn sich Ihr Datensatz häufig ändert, führt die Verwendung verschachtelter Dokumente zu einer großen Anzahl von Aktualisierungen. Eltern-Kind-Beziehungen Eltern-Kind-Beziehungen nutzen den , um Objekte mit Beziehungen vollständig in einzelne Dokumente – übergeordnete und untergeordnete Dokumente – zu trennen. Dadurch können Sie Dokumente in einer relationalen Struktur in separaten Elasticsearch-Dokumenten speichern, die separat aktualisiert werden können. Join-Datentyp Eltern-Kind-Beziehungen sind von Vorteil, wenn die Dokumente häufig aktualisiert werden müssen. Dieser Ansatz eignet sich daher ideal für Szenarien, in denen sich die Daten häufig ändern. Grundsätzlich teilen Sie das Basisdokument in mehrere Dokumente auf, die übergeordnete und untergeordnete Dokumente enthalten. Dadurch können sowohl die übergeordneten als auch die untergeordneten Dokumente unabhängig voneinander indiziert/aktualisiert/gelöscht werden. Suchen in übergeordneten und untergeordneten Dokumenten Um die Leistung von Elasticsearch während der Indizierung und Suche zu optimieren, wird allgemein empfohlen, sicherzustellen, dass das Dokument nicht groß ist. Sie können das Eltern-Kind-Modell nutzen, um Ihr Dokument in separate Dokumente zu unterteilen. Allerdings gibt es bei der Umsetzung einige Herausforderungen. Übergeordnete und untergeordnete Dokumente müssen an denselben Shard weitergeleitet werden, damit die Zusammenführung während der Abfragezeit speicherintern und effizient erfolgt. Die übergeordnete ID muss als Routing-Wert für das untergeordnete Dokument verwendet werden. Das Feld stellt Elasticsearch die ID und den Typ des übergeordneten Dokuments zur Verfügung, wodurch die untergeordneten Dokumente intern an denselben Shard wie das übergeordnete Dokument weitergeleitet werden können. _parent Elasticsearch ermöglicht Ihnen die Suche anhand komplexer JSON-Objekte. Dies erfordert jedoch ein gründliches Verständnis der Datenstruktur, um daraus effizient Abfragen durchführen zu können. Das Eltern-Kind-Modell nutzt mehrere Filter, um die Suchfunktion zu vereinfachen: Abfrage has_child Gibt übergeordnete Dokumente zurück, die über untergeordnete Dokumente verfügen, die der Abfrage entsprechen. Abfrage has_parent Akzeptiert ein übergeordnetes Element und gibt untergeordnete Dokumente zurück, die mit den zugehörigen übergeordneten Elementen übereinstimmen. Abfrage inner_hits Ruft relevante Kinderinformationen aus der Abfrage ab. has_child Abbildung 2 zeigt, wie Sie das Eltern-Kind-Modell verwenden können, um Eins-zu-viele-Beziehungen zu demonstrieren. Die untergeordneten Dokumente können ohne Auswirkungen auf das übergeordnete Dokument hinzugefügt/entfernt/aktualisiert werden. Das Gleiche gilt für das übergeordnete Dokument, das ohne Neuindizierung der untergeordneten Dokumente aktualisiert werden kann. Abbildung 2: Eltern-Kind-Modell für Eins-zu-Viele-Beziehungen Herausforderungen bei Eltern-Kind-Beziehungen Durch den Join-Vorgang sind Abfragen teurer und speicherintensiver. Bei übergeordneten und untergeordneten Konstrukten entsteht ein Mehraufwand, da es sich um separate Dokumente handelt, die zum Zeitpunkt der Abfrage zusammengeführt werden müssen. Es muss sichergestellt werden, dass das übergeordnete Element und alle seine untergeordneten Elemente auf demselben Shard vorhanden sind. Das Speichern von Dokumenten mit Eltern-Kind-Beziehungen erfordert eine komplexe Implementierung. Abschluss Die Wahl des richtigen Elasticsearch- ist entscheidend für die Anwendungsleistung und Wartbarkeit. Beim Entwerfen Ihres Datenmodells in Elasticsearch ist es wichtig, die verschiedenen Vor- und Nachteile jeder der vier hier besprochenen Modellierungsmethoden zu beachten. Datenmodellierungsdesigns In diesem Artikel haben wir untersucht, wie verschachtelte Objekte und Eltern-Kind-Beziehungen SQL-ähnliche Join-Operationen in Elasticsearch ermöglichen. Sie können in Ihrer Anwendung auch benutzerdefinierte Logik implementieren, um Beziehungen mit anwendungsseitigen Verknüpfungen zu verarbeiten. Für Anwendungsfälle, in denen Sie mehrere Datensätze in Elasticsearch zusammenführen müssen, können Sie beide Datensätze aufnehmen und in den Elasticsearch-Index laden, um eine leistungsstarke Abfrage zu ermöglichen. Standardmäßig verfügt Elasticsearch nicht über Joins wie in einer SQL-Datenbank. Es gibt zwar mögliche Problemumgehungen für die Herstellung von Beziehungen in Ihren Dokumenten, es ist jedoch wichtig, sich der Herausforderungen bewusst zu sein, die jeder dieser Ansätze mit sich bringt. Verwenden von Native SQL-Joins mit Rockset Wenn mehrere Datensätze für Echtzeitanalysen kombiniert werden müssen, kann eine Datenbank, die native SQL-Joins bereitstellt, diesen Anwendungsfall besser bewältigen. Wie Elasticsearch wird Rockset als Indexierungsschicht für Daten aus Datenbanken, Ereignisströmen und Data Lakes verwendet und ermöglicht die schemalose Aufnahme aus diesen Quellen. Im Gegensatz zu Elasticsearch bietet Rockset die Möglichkeit, , einschließlich Joins, durchzuführen, was Ihnen mehr Flexibilität bei der Verwendung Ihrer Daten gibt. Abfragen mit SQL mit vollem Funktionsumfang Auch veröffentlicht. hier