Kombinieren Sie relationale DB und elastische Suche

7

Wir haben eine große Anzahl von Textdateien, die wir für die Freitext- / Volltextsuche verwenden möchten, kombiniert mit relational strukturierten Metadaten über die Textdatei. Eine Suche könnte also lauten: "Geben Sie mir alle Dateien, die zur Gruppe X (oder zu Untergruppen von X) gehören, einen Autor haben (Ari und Bari und Mari), zur Organisation Y gehören und den Text" synthetisch "enthalten. Letzterer Teil Dies ist eine Volltextsuche, und die andere wird bereits als relationale Daten in unserer vorhandenen Datenbank gespeichert.

In unserer Datenbank (die ziemlich komplex ist) gibt es eine Möglichkeit, die Dateien zu identifizieren, und eine Menge verschiedener Metadaten über die Datei, die auf zehn Tabellen verteilt sind, von einfachen 1-1-Beziehungen bis zu 1-viele-Mengen pr Datei und sogar Baum-Struktur-Beziehung (Dinge wie "Diese Datei ist vom Typ X, Typ X ist eine Untergruppe vom Typ Y usw.). Und diese Metadaten können sich im Laufe der Zeit in der gesamten Anwendung ändern (was sehr groß ist).

Als Datenbankadministrator dachte ich nun, dass dies gelöst werden könnte, indem SQL Server verwendet wird, um nach strukturierten Metadaten zu suchen, die sich bereits in der Datenbank befinden, die Suche auf Kandidatendateien beschränkt und dann die IDs der Kandidatendatei an die elastische Suche nach Volldateien übergeben werden. Textsuche. (Das erneute Indizieren der Datei auf elastisch, wenn eine Datei hinzugefügt oder festgeschrieben wird, ist in unserem Code trivial.)

Die Elastic-Jungs in unserem Projekt hatten natürlich eine andere Idee: Alle Metadaten sowie den Volltextinhalt aus den Dateien zu extrahieren, die Elastic-Suche durchzuführen und die Suche ausschließlich in Elastic durchzuführen.

Auf diese Weise können sie problemlos Lucene-Abfragen mit voller Leistung ausführen, und die Datenbank wird entladen, was sehr hilfreich ist. Dies führt jedoch auch für mich zu einem Albtraum, um die strukturierten Metadaten synchron zu halten, und eine blinde Neuindizierung / Synchronisierung aller Elemente ist aufgrund des Datenumfangs nicht möglich.

Ich kann die Vorzüge / Bedenken beider Optionen erkennen. Gibt es eine bewährte Methode für diese Art von Dingen?

Henrik Alstad
quelle
Sind alle Rohoperationen in einer Reihe von Funktionen der Geschäftsschicht zentralisiert? Laufen Sie in einem Rechenzentrum oder bei einem Cloud-Anbieter?
Aaron
@ Aaron Ja, die Rohoperationen sind in einer Reihe von Funktionen der Geschäftsschicht zentralisiert. Aber es gibt Unmengen davon in einer riesigen Legacy-Anwendung, so dass es nicht einfach ist, alle Verwendungen zu protokollieren / zu synchronisieren und sich daran zu erinnern, dies in Zukunft zu tun (zukünftige potenzielle Fehler) - aber natürlich möglich. Wir arbeiten in einem Rechenzentrum.
Henrik Alstad

Antworten:

3

Verwende beide.

Hier müssen Sie und Ihr Team eine Linie ziehen. SQLSERVER ist teurer als ElasticSearch. Wenn ich also auf ein ähnliches Problem stieß, war es sinnvoller, CPU-Ressourcen für elasticsearch als für sqlserver auszugeben.

Es gibt einige Dinge, die Sie dazu bringen können, Ihre Textdaten in elasticsearch zu indizieren

Welche Art von Ladung sehen Sie?

Ein paar Suchanfragen pro Minute oder Dutzende pro Sekunde? Dies ist subjektiv, aber wenn ein großer Teil Ihrer Datenbankressourcen für diese eine Abfrage ausgegeben wird, möchten Sie diese möglicherweise auslagern.

Halten Sie Ihre Daten strukturiert

Ich finde die Abfragesprache von elasticsearch weitaus weniger intuitiv als SQL. Ich empfehle dringend, eine möglichst normalisierte Version Ihrer Daten in einer relationalen Standarddatenbank zu haben. Dann stützen Sie Ihren elastischen Index darauf.

Elasticsearch eignet sich in vielerlei Hinsicht hervorragend, aber das Schreiben komplexer Ad-hoc-Abfragen mit Aggregationen und / oder Unterabfragen gehört nicht dazu.

Wie synchronisieren Sie dann die Daten?

Trigger und Warteschlangen habe ich verwendet.

Fügen Sie der Tabelle einen Trigger hinzu, der Daten enthält, die Sie verfolgen möchten. So sieht eine der Warteschlangen aus, die ich erstellt habe.

Warteschlange

Der Trigger protokolliert die Aktion (Einfügen / Aktualisieren / Löschen) und von dort aus wissen Sie, was in Ihrem Elasticsearch-Index zu tun ist. Ich habe festgestellt, dass der Wiederaufbau der gesamten Platte in Gummiband nicht zu teuer war, also mache ich das so.

Auf diese Weise können Sie ein Projekt mit einer großen Codebasis erstellen und beliebige Daten in elasticsearch indizieren, ohne Codeänderungen vornehmen zu müssen. Alles wird durch den Status Ihrer Daten in Ihrem RDBMS Ihrer Wahl geregelt.

Elasticsearch (und alle anderen NOSQL- / Dokumentenspeicher) haben erstaunliche Anwendungsfälle, aber das Speichern relationaler Daten als Hauptdatenbank gehört nicht dazu. Verwenden Sie dazu relationale Datenbanken.

EIN V
quelle
Ich werde definitiv beide verwenden. SQL Server für relationale / strukturierte Daten und Elastic für die Volltextsuche. Frage ist die "Daten in der Mitte", dh die strukturierten Daten, die auch Teil der Suche sein werden. Wenn wir es reduzieren und zur elastischen Suche duplizieren, verbessert es die Leistung und lässt elasticsearch den gesamten Abfragevorgang ausführen. Wie Sie bereits erwähnt haben, müssen wir die Daten synchronisieren. Ein AFTER-Trigger kann dies tun, wie Sie bereits erwähnt haben. Dies kann sehr teuer sein, da die Tabellen sehr häufig aktualisiert werden. Ich könnte mehr verlieren als gewinnen, sogar nur die Leistung zählen
Henrik Alstad
Die Datenbank, in der ich einen solchen Prozess installiert habe, enthält auch eine große Anzahl von Updates. Der Auslöser selbst ist nicht der schwerste Teil des Prozesses. Das Abflachen der Daten in eine Zeile, um der Dokumentform von Elastic zu entsprechen, ist für mich ziemlich schwer. Selbst wenn 100.000 Aktualisierungen in der Tabelle vorhanden sind, wurde häufig derselbe Datensatz aktualisiert, sodass möglicherweise nur 1000 eindeutige Datensätze synchronisiert werden müssen. Zu diesem Zeitpunkt läuft es darauf hinaus, die Abfrage zu optimieren und die Verarbeitungsressourcen von Ihrem Datenbankserver zu entfernen, um die Kosten zu senken -effizient.
A_V