Anmerkungen zur DIH-Architektur: Der Datenimport-Handler von Solr

Was die Welt wirklich braucht, sind einige großartige Beispiele für die Erweiterung von DIH(Solr DataImportHanlder), die über die Klassen und…

Was die Welt wirklich braucht, sind einige großartige Beispiele für die Erweiterung von DIH(Solr DataImportHanlder), die über die Klassen und Unit-Tests hinausgehen, die mit Solr ausgeliefert werden. Angesichts der Komplexität von DIH ist das eine große Aufgabe, und leider ist dieser Beitrag auch nicht die Lösung! Nach vielen Recherchen im Internet glaube ich nicht, dass bisher jemand einen „Extending DIH Guide“ geschrieben hat – alle verweisen immer noch auf das Solr-Wiki, den Schnellstart, die FAQ, den Quellcode und die Unit-Tests.

In diesem Beitrag werde ich jedoch einige Konzepte vorstellen, die Sie im Hinterkopf behalten sollten. Und wer weiß, vielleicht habe ich in einem zukünftigen Beitrag auch konkreten Code.

Wenn ich Notizen mache, hebe ich die Dinge hervor, die sich von dem unterscheiden, was ich erwarte und warum. Natürlich verfügt DIH über eine XML-Konfiguration, in der Sie Ihre Datenbank, Ihr Dateisystem oder Ihren RSS-Feed angeben und diese Dinge auf Ihr Solr-Schema abbilden können – keine Überraschung. Aber die Schichtung dieser Konfiguration hat mich wirklich überrascht (und wie sich herausstellt, gibt es dafür gute Gründe).

Was ich zu finden erwartete (was nicht korrekt ist)

  • Oberste Ebene: Definieren Sie Verbindungen zu einer Datenbank, einer Website oder einem Dateisystem, einschließlich Ihrer SQL-Join-Abfrage, Dateisystem-Suchmuster oder URL-Parameter. Ich hatte die DataSource-Tags gesehen und angenommen, dass es sich dabei um diese handelt.
  • Mittlere Ebene: Definieren Sie Ihr Dokument, die logische Einheit des Abrufs, mit Hilfe des Tags <document>.
  • Niedrige Ebene: die Felder, die Sie kopieren oder in bestimmte Solr-Felder mit dem Tag <field> abbilden möchten.

Wie die DIH-Konfiguration tatsächlich aufgebaut ist:

  • Oberste Ebene: Hier definieren Sie oft eine DataSource, aber nicht immer. Und selbst wenn Sie sie hier definieren, ist dies nicht der Ort, an dem Sie Ihre SQL-Abfrage platzieren! Außerdem geben verschiedene Datenquellen völlig unterschiedliche Java-Typen zurück, entweder Reader oder Streams oder komplexe verschachtelte Datenstrukturen. Ich fand es wirklich überraschend, dass dieselbe Methode, die in einer Schnittstelle definiert ist, so grundlegend unterschiedliche Datentypen zurückgibt.
  • Mittleres Niveau: Das Dokument-Tag steht ganz oben, und in einigen wenigen Fällen gibt es kein DataSource-Tag.
  • Mittlere Stufe: Dies ist eine Kombination aus Entity-Prozessoren und Transformatoren. Aber die Entitäten definieren die SQL-Befehle oder Dateisystemparameter usw. Sie können auch verschachtelt sein und haben das Attribut „root“, das nicht immer dem höchsten <Entity> Tag im Baum entspricht.
  • Niedriges Niveau: Ich war ziemlich nah dran an dem <Feld> Tag, obwohl es mächtiger ist, als ich dachte.

Entitäten sind König

Die <Unternehmen> Tag ist wirklich der Star der Show! Wenn Sie darüber nachdenken, DIH für ein benutzerdefiniertes Repository zu erweitern, besteht sogar die Möglichkeit, dass Sie statt einer DataSource einfach einen neuen EntityProcessor erstellen. Ein Beispiel hierfür ist der EmailEntityProcessor.

Es ist zunächst befremdlich, dass eine SQL-Abfrage dem Tag <document> untergeordnet ist. Ich denke bei „Dokument“ an eine einzelne Zeile in einer Datenbank und einer Suchmaschine, während eine SQL-Abfrage eine ganze Reihe von Zeilen, eine Ergebnismenge, darstellt. Selbst wenn Sie Joins zu Hilfstabellen zulassen, um ein paar zusätzliche Felder zu erfassen, steht die Haupttabelle (ein Haufen Zeilen) logischerweise über einem Dokument (eine einzelne Zeile) – es ist fast wie eine foreach-Schleife, bei der der Code für die oberste Iteration versehentlich mit dem Code vertauscht wurde, der auf jedes Element wirkt.

Es stellt sich heraus, dass bei Entitäten, die als „root“ gekennzeichnet sind, jedes Dokument immer noch einem einzelnen Datensatz entspricht – DIH stopft offensichtlich nicht alle Ihre Datensätze in ein einzelnes Dokument! – Betrachten Sie es eher so, als ob die SQL einen Cursor definiert, der für jede Zeile, auf die er trifft, ein Dokument instanziiert. Ich denke, dies geschah aus Gründen der Konsistenz mit der SQL, die in den NON-root Entitäten erscheint, was auf dieser Ebene durchaus Sinn macht.

Entitäten, die nicht zur Wurzel gehören, können zusätzliche SQL-Abfragen durchführen und dabei Werte aus dem aktuellen Ergebnis der Wurzel-Entität verwenden, um zusätzliche Tabellen abzufragen (oder andere Datentypen zu holen, die dem Datensatz hinzugefügt werden). Wenn z.B. „Buch“ Ihre Hauptentität ist, kann eine andere Entität nach Autoren abfragen und einen oder mehrere von ihnen zum Buch hinzufügen. Dies ist besonders leistungsfähig für ein-zu-viele und viele-zu-viele Beziehungen. Bei einer normalen Verknüpfung würde der Hauptdatensatz wiederholt werden und ein Buch mit 3 Autoren würde 3 Solr-Datensätze statt 1 erzeugen.

Ein interessantes Beispiel dafür, dass die oberste Entität NICHT das Stammverzeichnis ist, ist das Wiki-Beispiel für das Scannen Ihres Dateisystems. Die oberste Entität aus XML-Sicht enthält die Informationen darüber, welches Dateisystemverzeichnis durchsucht werden soll und nach welchem Muster gesucht werden soll. Sie möchten jedoch nicht, dass eine bloße Verzeichnisauflistung ein tatsächlich durchsuchbares Dokument in Solr ist. Dies wird durch die Einstellung rootEntity=“false“ erreicht.

Was Sie wirklich wollen, ist, dass der Inhalt jeder Datei ein Datensatz in Solr wird. Dies geschieht durch eine verschachtelte Entität (aus XML-Sicht), die als rootEntity=“true“ gekennzeichnet ist.

Ein anderes Beispiel wäre, wenn eine einzige XML-Datei mehrere Datensätze enthält. In einer komplexen Situation könnten Sie XML-Prozessoren verschachteln, aber trotzdem nur denjenigen als Stamm markieren lassen, der den Solr-Dokumenten entsprechen soll.

Eventuell werden einige der Entitäten <Feld> Tags enthalten. Hier können Sie Datenbank- oder XML-Daten in ein Solr-Schema abbilden. Sie können auch Transformatoren für jedes Feld aufrufen. Und das Schöne daran ist, dass die Feldtransformatoren Zugriff auf alle gebundenen Variablen sowie auf die anderen Feldwerte haben, die Sie gerade berechnet haben. Der Tika-Prozessor kann auch andere Dokumenttypen wie MS Word oder Excel verarbeiten, die vielleicht auch in Ihrer CMS-Datenbank vorhanden sind.

Tieferes Nesting

Und die Geschichte wird sogar noch interessanter. Was wäre, wenn Sie XML-Daten hätten, die Sie in DIH verarbeiten wollten, diese aber in einer Datenbank statt im Dateisystem oder in einem einfachen RSS-Feed gespeichert wären? Und was wäre, wenn Sie, um diese XML-Inhalte aus einer Datenbank abzufragen, tatsächlich Joins durchführen müssten, um Metadaten aus anderen Tabellen einzuholen? Kein Problem – DIH bietet Ihnen eine Lösung! Die oberste Entität würde die Abfrage an die Hauptdatenbanktabelle einrichten, und Sie könnten andere Entitäten haben, die Joins zu anderen Tabellen durchführen. Und wenn Sie schließlich den XML-Inhalt abrufen, können Sie CLOB- und XML-Entity-Prozessoren darunter schachteln, um zusätzliche Schlüsselwerte mit XPath herauszuziehen. DIH kann also SQL, XPath, Regex zum Bereinigen und jede beliebige Skriptsprache in einer einzigen Konfigurationsdatei kombinieren, oft ohne dass Sie Java-Code schreiben müssen – DAS IST COOL. Ich weiß, dass es eigenständige ETL-Produkte gibt, die noch mehr können, aber DIH ist quelloffen und bereits in Solr integriert, so dass es sehr praktisch ist, es zu nutzen.

Ich denke, diese enorme Flexibilität bei der Darstellung von verschachtelter Geschäftslogik in Entitäten und die ganze Maschinerie zur Datenumwandlung ist der Grund, warum DIH zunächst etwas abschreckend wirkt. DIH verfügt über genügend Intelligenz, um die „Pipelines“ anderer Produkte wie FAST ESP zu ersetzen. Als Bonus werden Sie ermutigt, zusätzliche Abfragen zu erstellen, um mehr Daten zu erhalten. Obwohl dies in ESP technisch möglich war, wurde davon abgeraten, und Sie mussten sich wirklich selbst darum kümmern.

DIH verlängern

Wenn Sie ein Java-Programmierer sind und aus den vorhandenen Komponenten nicht das zusammenstellen können, was Sie brauchen, dann ist es vielleicht an der Zeit, den Compiler auszupacken. Es gibt eine ganze Reihe von Entity-Typen und Transformers im Wiki.

Je nachdem, was Sie brauchen, könnte eine Erweiterung von DIH auch zu viel des Guten sein. Erik Hatcher hat einen schönen Blogbeitrag über die Indizierung mit SolrJ geschrieben, der vielleicht einfacher ist.

Wenn ich Ihnen das immer noch nicht ausgeredet habe, dann geht es jetzt los!

Der Hauptcode von dataimporthanlder befindet sich im Bereich contrib modules in Solr, und alles ist im Paket org.apache.solr.handler.dataimport enthalten. Es gibt auch ein zweites contrib-Modul namens dataimporthandler-extras für Tika und Email. Es ist separat, um die Abhängigkeiten teilweise zu trennen.

Wie ich oben schon sagte, könnten Sie in Erwägung ziehen, den Code des EntityProzessors anstelle des DataSource-Codes zu erweitern. Ich denke immer noch über die Auswirkungen der beiden Möglichkeiten nach.

Es gibt vier Orte, von denen aus Sie DIH verlängern können:

  • DataSource
  • EntityProcessor (verwenden Sie EntityProcessorBase)
  • Transformator
  • Bewerter

Es gibt drei Hauptfamilien von DataSources, die ich nach ihrem Rückgabetyp unterschieden habe:

  • Binäre Daten – liefert <InputStream>
  • Textuelle Daten – liefert <Reader>
  • Datensatzbasierte Daten – liefert Iterator<Map<String, Object>>>

Einige andere Klassen, die Sie beachten sollten:

  • ContextImpl teilt Ihnen alles über die eingehende Anfrage, Ihr Schema usw. mit.
  • EventListener – zapfen Sie alles an, was vor sich geht, erstellen Sie Rückrufe, usw.
  • VariableResolver und benutzerdefinierte Evaluatoren – für den Fall, dass Sie eine ältere Vorlagensprache haben (Sie würden VariableResolver nicht erweitern, aber es ist gut, sich dessen bewusst zu sein)
  • DIHWriter, SolrWriter und DocBuilder bringen Ihre Daten in Solr (Sie würden diese nicht erweitern, aber auch gut zu wissen)
  • MockDataSource befindet sich unter dem Hauptcode-Zweig (vs. test) und gibt Record-ähnliche Daten zurück (<Iterator<Map<String, Object>>>) – dies könnte hilfreich sein, wenn dies die Art von Daten ist, mit denen Sie arbeiten
  • AbstractDataImportHandlerTestCase befindet sich drüben im Quellcode der Unit-Tests und ist ein guter Ausgangspunkt für das Schreiben Ihrer Tests. Sie können sich auch die anderen Tests ansehen, die diese Funktion verwenden, um sich Anregungen zu holen.

Ich würde gerne hören, was Sie mit DIH machen, insbesondere wenn Sie es tatsächlich erweitert haben.

You Might Also Like

Vom Suchunternehmen zum praktischen KI-Pionier: Unsere Vision für 2025 und darüber hinaus

CEO Mike Sinoway gibt Einblicke in die Zukunft der KI und stellt...

Read More

Wenn KI schief geht: Fehlschläge in der realen Welt und wie man sie vermeidet

Lassen Sie nicht zu, dass Ihr KI-Chatbot einen 50.000 Dollar teuren Tahoe...

Read More

Lucidworks Kernpakete: Branchenoptimierte KI-Such- und Personalisierungslösungen

Entdecken Sie unsere umfassenden Core Packages, die Analytics Studio, Commerce Studio und...

Read More

Quick Links