Apache Lucene sucht weiter, Teil 3

Solr, der Suchserver

Bernd Fondermann

Runterladen, auspacken, starten, lossuchen. Diese Losung gibt das Team von Apache Lucene für sein Produkt Apache Solr aus und ermöglicht damit Suche, ohne eine einzige Zeile Sourcecode zu schreiben.

Wenn jeder heutzutage sein Linux selbst installieren kann, dann sollte dies mit einem Suchserver ebenfalls kein Ding der Unmöglichkeit sein. Solr kommt als ZIP File daher, setzt ein installiertes Java voraus und entpackt sich in einen Ordner namens „apache-solr-1.3.0“. Wechselt man in das Unterverzeichnis „apache-solr-1.3.0/example“, lässt sich von dort ein vorkonfigurierter Server starten, inklusive Weboberfläche: „java -jar start.jar“. Mit der Verwaltung unter dem URL http://127.0.0.1:8983/solr/ beschäftigen wir uns später, zunächst wollen wir ein paar Daten in unseren schnell installierten neuen Server hochladen.

Post für Lucene

In den letzten beiden Folgen haben wir die dokumentenorientierte Architektur von Lucene behandelt. Sie findet auch in Solr ihre Anwendung. Eine Webschnittstelle steht für das Hinzufügen und Ändern von Dokumenten zur Verfügung. Während man für Lucene in der Regel Java programmieren muss, ist Solr wesentlich zugänglicher: HTTP-POST und XML kann heutzutage wirklich jeder, von Shell-Kommandos wie curl über Ruby bis zu C# – der Interoperabilität sind keine Grenzen gesetzt. Konkret wird ein Dokument mit wenigen XML-Elementen beschrieben, eines für jedes Feld. Für ein Dokument mit der ID „CVG180727“ und dem Namen „Dole mi fa sole“ wäre das:

<add>
<doc>
<field name=“id“>CVG180727</field>
<field name=“name“>Dole mi fa sole</field>
</doc>
</add>

Den allseits bekannten XML-Vorspann („?xml…“), doctype-Deklarationen etc. kann man sich tatsächlich sparen, es zählt nur der für den Index unmittelbar relevante Inhalt.

Solr liefert uns die Bordmittel, um diese Daten in den Index zu schreiben, wenn wir dafür sorgen, sie als Datei (nehmen wir als Namen „product.xml“ an) bereitzuhalten. Im Verzeichnis „apache-solr-1.3.0/example/exampledocs“ findet sich dafür ein JAR, dem man ein XML File als Parameter mitgeben kann:

java -jar exampledocs/post.jar product.xml

Dieses Miniprogramm überträgt per HTTP-POST das File an den Server. Dies klappt natürlich auch über Rechnergrenzen hinweg, also wenn Solr z.B. auf einem zentralen Server läuft.

Felder

Im Unterschied zu Lucene sind Dokumente in Solr nicht Schema-frei. Das bedeutet, dass nur vordefinierte und nicht beliebige Felder belegt werden können. Wie kommt es dann, dass verflixterweise unser Beispieldokument mit den Feldern „id“ und „name“ vom Server akzeptiert wird? Nun, an dieser Stelle habe ich getrickst, um dem verehrten Leser einen schnellen Erfolg zu bescheren. Diese beiden Felder sind nämlich ganz zufällig in der Beispielkonfiguration von Solr vordefiniert. Ein beliebiger Feldname würde zu einem Fehler führen:

<add>
<doc>
<field name=“product_id“>CVG180727</field>
<field name=“product_name“>Dole mi fa sole</field>
</doc>
</add>

Dieses Dokument wird nicht akzeptiert. Es erscheint die etwas unzureichend formatierte Antwort:

SimplePostTool: Solr returned an error: ERRORunknown_field_product_id

Nimmt man diese Meldung vorsichtig auseinander, erkennt man, dass hier ein unbekanntes Feld namens „product_id“ angemeckert wird. Nun gibt es zwei mögliche Herangehensweisen, um die eigenen Felder nach Solr zu bringen: über DynamicFields oder über das Anpassen des Schemas.

DynamicFields

Mit dem Schema werden wir uns noch eingehender beschäftigen, deswegen zuerst zu den DynamicFields. Sie sind eine Eigenart von Solr, die eine gewisse Varianz in die erlaubten Feldnamen bringt, indem kein eindeutiger Feldname, sondern ein regulärer Ausdruck definiert wird. Damit wird das strenge Schema etwas flexibler. Aus dem Reigen aller DynamicFields wird das Feld dort einsortiert, wo es als Erstes auf den Feldnamen passt.

In der Default-Konfiguration ist es möglich, durch Anhängen von „_s“ an den nicht explizit unterstützten Feldnamen das DynamicField vom Typ String anzusprechen, im Folgenden versuchen wir es mit product_name_s:

<add>
<doc>
<field name=“id“>CVG180727</field>
<field name=“product_name_s“>Dole mi fa sole</field>
</doc>
</add>

Schema-Überblick

Verschaffen wir uns einen Überblick über die vordefinierten Schema-Felder, um nachzuvollziehen, was eigentlich passiert ist. Dazu surfen wir am besten den URL http://localhost:8983/solr/admin/schema.jsp im bevorzugten Webbrowser an. Die aktuelle Konfiguration von Solr ist über diese kleine Webanwendung zugreifbar. Das hier besprochene Beispielschema ist außerdem offline im XML File „apache-solr-1.3.0/example/solr/conf/schema.xml“ zu finden.

Auf der linken Seite unterhalb von HOME sind die Menüpunkte „FIELDS“, „DYNAMIC FIELDS“ und „FIELD TYPES“ zu sehen.

Unter „FIELDS“ erblicken wir neben einigen anderen Feldnamen die uns schon bekannten: „ID“, „NAME“, sowie „PRODUCT_NAME_S“. Es wurde also über den DynamicField-Mechanismus wirklich ein neues Feld angelegt. Die Eigenschaften („Properties“) dieses Feldes entsprechen genau denen, die wir unter „DYNAMIC FIELDS“/“*_S“ finden. DynamicFields verhalten sich also wie eine Schablone: Alle Namen, die auf die DynamicField-Schablone passen, werden zu ‚echten‘ Feldern im Server.

Vergessen wir nicht, dass hier eine Beispielkonfiguration von Solr zu sehen ist, die an das hypothetische Datenmodell eines Webshops angelehnt ist. Deswegen sehen wir Felder wie „CAT“, „WEIGHT“ und „SKU“. Eine Anpassung des Schemas auf die eigenen Bedürfnisse ist empfehlenswert. Dazu wird es notwendig, die Solr-Schema-XML-Datei zu bearbeiten und danach den Server zu stoppen und neu zu starten.

Strenge Typen, flexible Felder

In Lucene enthalten Felder grundsätzlich Text. In Solr sind Felder hingegen typisiert, ähnlich wie Variablen in Java. Die klassischen Typen wie Date, Float, Double, Integer, Long, Boolean und verschiedenen Arten von Text-Typen sind vordefiniert, eigene können ebenfalls verwendet werden.

Jedes Feld besitzt einen Typ, gegen den der Wert des Feldes beim Hinzufügen geprüft und gegebenenfalls abgelehnt wird. Des Weiteren wird in der Deklaration des Feldes festgelegt, welche Lucene-spezifischen Verarbeitungsschritte beim Indizieren vorgenommen werden sollen, ob eine Zerlegung stattfindet und ob es „suchbar“ sein soll. Außerdem können weitere spezialisierte Schritte, so genannte Filter, definiert werden, die bei Indizierung und Suche berücksichtigt werden sollen. Zum Beispiel können so die eingehenden Daten zu Kleinbuchstaben umgewandelt werden oder es lassen sich Wörter („Stopwords“) definieren, die auf keinen Fall in den Index aufgenommen werden sollen.

Hier nun zwei Feldtyp-Deklarationen, gefolgt von zwei Feld-Deklarationen, die diese Typen verwenden:

<fieldType name=“string“ class=“solr.StrField“ sortMissingLast=“true“ omitNorms=“true“/>

<fieldType name=“boolean“ class=“solr.BoolField“ sortMissingLast=“true“ omitNorms=“true“/>


<field name=“inStock“ type=“boolean“ indexed=“true“ stored=“true“/>

<field name=“word“ type=“string“ indexed=“true“ stored=“true“/>

Facetten

Eine wesentliche Errungenschaft von Apache Solr ist die facettierte Suche. Bei dieser wird das Suchergebnis nach und nach verfeinert, indem vorher ‚freie‘ Suchfelder fest belegt werden. Ein Beispiel: Ich durchsuche meine MP3-Sammlung nach dem Lied, das ich als Nächstes hören möchte. Es stehen hunderte Songs zur Auswahl. Deshalb wähle ich zunächst einen Wert im Feld Genre aus: „Jazz“. Damit verkleinert sich mit einem Schlag die Treffermenge, denn Titel zu „Pop“, „Rock“, „Klassik“ und „Elektro“ fallen weg. Nun wähle ich aus den verbleibenden Treffern eine weitere Facette aus: „Artist“ mit dem Wert „Milt Jackson“. Nun fällt die endgültige Wahl nicht mehr so schwer…

Facetten werden als besondere Parameter bei der Übermittlung der Suchanfrage mitgegeben und in der Berechnung des Ergebnisses als Muss-Kriterien berücksichtigt. Sie gehen nicht in die Gewichtung ein, wie die anderen Terme der Abfrage. Facetten haben also den Effekt, dass eine Suche auf einer Teilmenge des Gesamtindexes sehr gute und unverfälschte Suchergebnisse liefert.

Sonnenkraft

Apache Solr ist viel mehr als nur ein GUI für Lucene. Es ist ein voll ausgewachsener Suchserver, optimiert für hohe Last und Verfügbarkeit. Dazu wurden Features hinzugefügt, die in Lucene selbst nicht zu finden sind. Drei Beispiele: Warm-up, Caching, Clustering.

„Warm-up“ bedeutet, dass der Server beim Start die Suchdatenbank analysiert und Daten ins RAM lädt, um sie dort vorzuhalten. Dieser Caching-Speicher wird fortlaufend aktualisiert, er enthält sowohl Suchergebnislisten für Teilabfragen als auch dazugehörige Dokumente. Kann eine Abfrage aus dem Cache beantwortet werden, erhöht sich der Durchsatz und die Zugriffe auf den unterliegenden Suchindex werden verringert. Davon können Nutzer profitieren, die hintereinander ähnliche Abfragen stellen oder einfach besonders populäre Anfragen absetzen.

Das „Clustering“-Feature ermöglicht den automatischen Betrieb desselben Indexes gleichzeitig auf mehreren Solr-Servern. Sind Solr-Instanzen zu einem solchen Verbund zusammengeschaltet, laden und integrieren sie regelmäßig die auf den jeweils anderen Maschinen geänderten Index-Daten. Damit können mehr Nutzeranfragen parallel beantwortet werden, und bei Wartungsarbeiten an einem Server übernehmen die anderen Rechner.

Highlights

Ergebnisse können statt als XML auch in anderen Formaten wie z.B. JSON übertragen werden. Um dem Nutzer anzeigen zu können, welche Wörter des zurückgelieferten Ergebnisses den Treffer ausgelöst haben, werden diese im Ergebnis separat mitgeliefert. Anhand dieser Information kann man dann visuelle Hervorhebungen bei der Darstellung des Treffers einbauen. Doch das ist nicht alles. Wenn man sich alleine die Liste der Features anschaut, staunt man nicht schlecht. Dies erinnert an die Mächtigkeit von relationalen Datenbanken wie Oracle und Co.

In der nächsten Folge geht es anhand von Apache Nutch und Apache Tika darum, Dokumente von verschiedensten Orten und aus unterschiedlichsten Quellformaten zu indizieren.

Bernd Fondermann (bernd.fondermann[at]brainlounge.de) ist freiberuflicher Softwarearchitekt und Consultant in Frankfurt a. M. Er beschäftigt sich mit innovativen Open-Source-Technologien bei der Apache Software Foundation und ist derzeit PMC Chair und Vice President Apache Labs.

Geschrieben von
Bernd Fondermann
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.