Vorwort: wieso ein Blog zu PHP, Solr und Lucene?

Wieso ein Blog zu PHP, Solr und Lucene?
Gegenstand und Ausgangspunkt all unserer Aktivitäten auf diesem Gebiet war ein Projekt um ein Nachrichtenportal und die Aufgabe, Recherchen und Analysen im Nachrichtenbestand von über 10 Million News performant zu handeln. Die MySQL Volltextsuche kam da schnell an Ihre grenzen, Oracle war keine Alternative.
Es reifte also die Frage, wie können andere (etwa die Internetsuchmaschiene google) immense Datenmengen spielend handeln?
Wir lösten den MySQL volltext mit Lucene ab. Der Performancegewinn war dramatisch. Suchen im Datenbestand, die vorher über 10 Sekunden dauerten, brauchen mittels Lucene und Solr nur selten mehr als 20ms!
Eine neue Welt tat sich auf, die es zu erobern galt und schnell fiel auf, dass deutschsprachige Seiten zum Thema Mangelware sind. Dies soll sich mit diesem Blog ein wenig ändern.

Sie haben Fragen zu Solr/Lucene/PHP? Schreiben sie uns einen Kommentar!

Montag, 13. Januar 2014

mongoDB Data Import Handler für Solr

Wie bereits im vorhergehenden Post beschrieben ist derzeit keine Software im Netz verfügbar, die zum einen gepflegt wird und zum anderen performant große Datenmengen einer mongoDB in Solr indexiert.
Die Lösung für uns bestand darin, selber ein kleines Tool zu schreiben, dessen Aufgabe initial darin bestand, eine mongoDB komplett nach Solr zu importieren.

Ich habe es unter github abgelegt, für jedermann zugänglich: mongoSolrImporter


Der klassische Data Import Handler von Solr ist in Solr selber integriert. Der mongoSolrImporter arbeitet im Gegenzug dazu autark als externe PHP Skript.
In einer Konfigdatei werden dazum Solr Server, mongoDB Host, das Field-Mappiung und die mongoDB Query angegeben. Die Konfigurationsdatei wird dann dem Skript übergeben

user@host> php mongoSolrImporter.php -c mongoSolrImporter.ini

..und schon kanns losgehen.
Die Daten werden Blockweise in Solr indexiert. Dadurch wird im Vergleich zum mongo-connetor eine deutliche Performancesteigerung. der mongoSolrImporter verarbeitet pro Sekunde 2500 Dateien, wenn man auf einem Linuxsystem arbeitet über 6500 Dateien pro Sekunden, während der mongo-connector bei gleichem Datenbestand auf der gleichen Hardware etwa 33 Dokumente pro Sekunde verarbeitet. Der Geschwindigkeitsgewinn liegt folglich beim Faktor 200.

Zudem basieren die Daten auf einer Query, nicht auf dem oplog der mongoDB. Sind also auch bei abgelaufenem oplog noch greifbar.

Die Beschränkung liegt allerdings in der bisher mangelnden Unterstützung von mongoDB Datentypen. Initial ist das Tool so designt, dass mongoDB Daten verarbeitet werden, die ursprünglich aus einer relationalen Datenbank kommen. Die also keine Arrays oder embedded documents haben.

Dienstag, 7. Januar 2014

Synonyme und explizites Mapping

Wir haben ein paar Erkenntnisse aus einer Problemstellung mit Synonymen gewinnen können, die im Folgenden an einem fiktivem Beispiel erklärt werden sollen.

Dabei ist zu beachten: Wir erstellen Synonyme immer zur Index-Zeit, wie von SOLR empfohlen!

Problem
Nehmen wir einmal an, wir betreiben eine Webseite für Naturliebhaber und möchten, dass eine Suche nach Amsel oder Drossel oder Fink oder Starr Artikel findet, in denen die jeweils genannte Vogelart als Term vorkommt.
Wenn ich jedoch nach Vogel suche, möchte ich, dass nicht nur Artikel gefunden werden, in denen der Suchterm Vogel enthalten ist, sondern auch jene Artikel gefunden werden, in denen der Suchterm zwar nicht vorkommt, jedoch eine Vogelart benannt wird.
Bisher haben wir das in der Synonymdeklaration wie folgt gelöst:

vogel, amsel, drossel, fink, starr

Hier ergibt sich jedoch ein Problem mit der Präzision der Suchergebnisse:
So findet eine Suche nach Amsel per Definition auch Artikel, in denen es lediglich um Finken oder Drosseln etc. geht, ohne das eine Amsel erwähnt werden muss. SOLR verhält sich hier nämlich wie folgt:

Artikel A enthält als relevanten Begriff das Wort Amsel.
Mit obiger Synonymdeklaration wird dann während der Indexierung nicht nur das Wort Amsel mit in den Index aufgenommen, sondern ebenso alle o.g. Synonyme (Drossel, Fink, Starr, Vogel).

Ähnliches gilt für Artikel B, der nur das Wort Fink enthält, und sonst keinen anderen der genannten Begriffe. Auch würden die Terme Drossel, Amsel, Starr und Vogel zu diesem Artikel in den Index aufgenommen werden.

Die Folge: Eine Suche nach Amsel würde nicht nur den Artikel A zurückliefern, sondern auch den Artikel B, wenngleich in B der Begriff Amsel garnicht vorkommt. Gleiches gilt für den Suchbegriff Fink, der ebenfalls beide Artikel liefern würde.

Eine Suche nach dem Begriff Vogel würde gleichfalls beide Artikel liefern, was in diesem Fall auch richtig und gewollt wäre, den Mangel bei den beiden anderen Suchen aber nicht ausgleichen kann.

Was wir grundsätzlich wollen: Wenn man einen speziellen Suchbegriff eingibt, soll er spezielle Artikel finden, wenn wir einen Oberbegriff verwenden, soll ein breit gefächertes Ergebnis erscheinen.

Lösung
Zunächst einmal müssen wir entscheiden, welcher Begriff ein spezieller Begriff ist und welcher Begriff als Oberbegriff gilt. Diese Definition obliegt dem jeweiligen Datenbestand etc.
Im obigen Beispiel fällt die Einordnung leicht.
Amsel ist der Spezialbegriff, Vogel der Oberbegriff.

Die Lösung für unser Problem iat das sogenannte explizite Mapping.
Während das obige Beispiel für eine Synonymdeklaration unbestimmt ist und alles mit allem kombiniert, bietet das explizite Mapping die Möglichkeit, festzulegen, welche Begriffe wie zueinander gemappt werden sollen.
In der Sache ist das ganz einfach, wobei es einen interessanten Knackpunkt gibt:

amsel => vogel

Hier wird unidirektional der Begriff Amsel durch den Begriff Vogel ersetzt!
Es ist nicht so, dass bei dieser Deklaration der sowohl Amsel als auch Vogel nach der Indexierung im Index vorhanden wären.
Eine Suche nach Amsel würde keinen Treffer ergeben, weil alle Vorkommen des Worte Amsel durch das Wort Vogel ersetzt worden wären!

Die einfachste Lösung, die für uns gut funktioniert:

amsel => vogel, amsel
drossel => vogel, drossel
fink => vogel, fink
[...] 

Jetzt verhält sich die Suche wie gewünscht: Eine Suche nach Amsel liefert wirklich nur Amsel-Artikel zurück, während die Suche nach dem Oberbegriff Vogel auch Artikel mit allen anderen Vogelarten findet.

Limitierungen
Die Pflege entsprechender Synonyme kann sehr mühselig und aufwendig sein. Aber das ist bei Synonymen unserer Erfahrung nach immer der Fall.