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, 24. Oktober 2011

Solr: Konvertirung von Umlauten: ae<->ä, oe< ->ö, ue <->ü (Unicode Collation)

Kürzlich erhielt ich einige Millionen Dokumente aus längst vergangenen Zeiten, die es zu indizieren galt. Das Problem dabei ist, dass ein Teil der Dokumente aus jener Zeit ist, in der deutsche Umlaute, als ö,ä,ü und ß  in der IT noch kein Thema waren.
Diese Umlaute wurden folglich umschrieben: oe statt ö, ue statt ü, ae statt ä und ss statt ß.

Umlaute mittels Lucene/Solr zu finden ist kein Problem. Ebenso lassen sich natürlich Umschriebene umlaute genauso finden.
Auf der anderen Seite kann man dem User nicht zumuten 2 Suchen abzufeuern, beispielsweise eine nach Schröder und eine nach Schroeder.

Ziel ist es also Solr so zu konfigurieren, dass Suchen nach Schröder auch Schroeder findet. Konkret, dass die Suche nach Wörtern mit  ü,ö,ä auch Wörter findet, die ein ue, oe,ae enthalten, dass Umlaute also konvertiert werden.

Freitag, 23. September 2011

OutOfMemoryException während der Index-Optimierung

Wir sind neulich auf ein interessantes Problem gestoßen:
Unser Index hatte eine Größe erreicht, bei der ein Optimize zu einer OutOfMemoryException führte.
Der wesentliche Teil der Catalina.out gab dabei Folgendes aus:


Caused by: java.lang.OutOfMemoryError: Map failed
>>>        at sun.nio.ch.FileChannelImpl.map0(Native Method)
>>>        at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:762)

Als ersten Versuch haben wir den RAM für die JVM höher gesetzt, allerdings mit dem zunächst verwirrenden Ergebnis, dass die OOE noch schneller geworfen wurde als zuvor.

Nach etwas Recherche ließ sich feststellen, dass die nio-Klasse außerhalb des Speichers der JVM wildert und folgedessen eine entsprechende Erhöhung eher Kontraproduktiv ist, da der nun von der JVM zusätzlich verwendete Speicher dem OS und damit der bio-Klasse fehlt. 

Letztendlich lässt sich das Problem einfach in den Griff bekommen. Man muss lediglich der Shell, in welcher die JVM läuft, per 'ulimit -v unlimited' genügend virtuellen Speicher zur Verfügung stellen. Normalerweise sollte es reichen, den ulimit-Befehl in jenes Init-Skript zu schreiben, mit welchem man die JVM, den Tomcat, Jetty - was auch immer - startet.

Wenn man wissen möchte, wie hoch der zur Verfügung stehende virtuelle Speicher von Hause aus ist, dann hilft ein 'ulimit -v'. Und man darf sich nicht täuschen lassen - wir hatten einen Vmem von ~14GB und unser Index hatte "nur" 5GB. Das sollte locker ausreichen, möchte man meinen. Tat es aber nicht. Bei einem Optimize landet man sehr schnell bei sehr hohem Speicherverbrauch.


Entscheidend ist, dass der ulimit-Befehl in jener Shell ausgeführt wird, in welcher die JVM läuft, denn ulimit scheint per se nur in der Shell zu gelten, in welcher er ausgeführt wurde. 

Montag, 8. August 2011

Gruppierung von Ergebnissen

Mit Solr 3.4 und Solr 4.0 kommt eine wunderbare, von mir schon lange vermisste Funktion hinzu: das gruppieren von Dokumenten in der Ergebnisliste.
Diese Funktion nennt sich "Field Collapsing" (oder auch "Result Grouping") und ist hier: http://wiki.apache.org/solr/FieldCollapsing beschrieben.

Mittwoch, 13. Juli 2011

Mehere Solr Instanzen parallel betreiben (solr.xml)

Hin und wieder ergibt sich die Notwendigkeit, eine zweite Solr Instanz aufzubauen.
Etwa dann, wenn weitere Dokumente mit einer anderen Struktur indexiert werden sollen. Ein zusätzlicher Solr Index ist auch dann sinnvoll, wenn man zwischen Entwicklungsindex und Produktivindex trennen möchte; in diesem Zusammenhang auch, um neue Konfigurationen auf einer Instanz zu testen, während die zweite Instanz unverändert weiter läuft.
Im Idealfall kann man ad hoc zwischen beiden Konfigurationsalternativen wechseln.

Natürlich könnte man dazu diverse J2EE Container (tomcat, Jboss, Ant,...) parallel betrieben. Der Administrationsaufwand ist dafür allerdings "oversized", dann für genau diese Anwendungsfälle sind parallel Betriebene Solr Cores geschaffen.

Mittwoch, 22. Juni 2011

schema.xml

Die schema.xml liegt üblicher Weise im conf Verzeichnis einer jeden SOLR Instanz  und dient zur Konfiguration des Lucene Index: wie werden Daten im Index gehalten und in wie weit werden sie noch bearbeitet (Stemming/Wortstammbildung, Stoppworte, etc)

Im ersten Moment wirkt diese Datei unübersichtlich und erschlagend. Tatsächlich ist sie aber nur voll gepackt mit Beispielen, die im konkreten Fall oftmals unnötig sind.

Die schema.xml kann man grob in 3 Bereiche unterteilen:

Donnerstag, 16. Juni 2011

Faceted Search / Analyse der Daten im Volltext

Facetted search ist ein sehr mächtiges und nützliches Feature.
Dabei werden Suchen ggf. nur auf Teilbereiche angewandt und Ergebnisse gruppiert.

1.) Beispiel: Personalverwaltungssystem