Sphinx: Suche ohne Rätsel

Die Volltextsuche Sphinx erlaubt die Indizierung beliebiger Datenbestände. Dabei kommt sie nicht nur mit Millionen von Dokumenten zurecht, sondern liefert auch gute Resultate.

Artikel erschienen in Swiss IT Magazine 2007/09

     

Zu den wichtigsten Bestandteilen von Webapplikationen oder Online-Angeboten gehört eine gute Suchmaschine. Doch wer nicht gerade Google für sich suchen lassen möchte, hat keine allzu einfache Aufgabe vor sich. Denn die wenigsten der freien Datenbanken bringen leistungsfähige Werkzeuge zur Volltextsuche mit. So unterliegt beispielsweise die Volltextsuche von MySQL, die eine der bekannteren ist, etlichen Restriktionen:



- Sie kann nur mit der Storage Engine MyISAM eingesetzt werden.



- Ein Volltext-Index kann nicht über mehrere Tabellen oder Datenbanken hinweg verwendet werden.


- Die verwendeten Algorithmen sind verhältnismässig primitiv.


- Sie ist langsam.


Separate Werkzeuge

So bietet sich der Einsatz von separaten Werkzeugen an, die auf Volltextsuche und grosse Textmengen spezialisiert sind. Das wohl beste freie Werkzeug ist das Java-Framework Lucene, das wir im Rahmen unserer Apache-Serie in InfoWeek 18/2006 bereits vorgestellt haben. Allerdings ist Lucene nicht ganz einfach zu bedienen und als Java-Software nicht unbedingt ideal für die Verwendung mit anderen Sprachen, sofern nicht eine einigermassen gleichwertige Implementierung existiert. Weniger ausgefeilt, dafür einfacher zu bedienen, ist Sphinx (www.sphinxsearch.com).


Google für Hausgebrauch

Sphinx (SQL Phrase Index) steht unter der GPL und läuft auf so ziemlich jedem unixoiden Betriebssystem, auf dem ein C++-Compiler wie g++ vorhanden ist. Windows wird ebenfalls unterstützt, unterliegt aber einigen Einschränkungen.
Sphinx ist grundsätzlich ein relativ einfach aufgebautes Werkzeug. Es besteht aus einem Indexer, der sich um das Indizieren der Datenbestände kümmert, dem Daemon searchd, der die Suchanfragen beantwortet, und dem Kommandozeilenwerkzeug search, das einem eine einfache Möglichkeit bietet, um Suchanfragen an den Sphinx-Daemon zu stellen.



Der Funktionsumfang ist dabei durchaus beachtlich. Neben einer hohen Geschwindigkeit beim Indizieren (bis zu 10 Megabyte pro Sekunde) und beim Suchen verträgt Sphinx auch grosse Textmengen von Dutzenden Gigabytes, wobei die Suchalgorithmen so ausgelegt sind, dass sie auch bei verhältnismässig kurzen Texten wie Blog Postings gute Resultate und Gewichtungen liefern. Gefunden werden können nicht nur Datensätze, die sämtliche Suchbegriffe enthalten, sondern auch solche, die nur einen Teil der Suchbegriffe oder komplette Phrasen enthalten. Zusätzlich besteht die Möglichkeit, Suchbegriffe mit boolschen Operatoren oder einer Sphinx-eigenen Sprache zu verwenden, wobei letztere sogar sogenannte Proximity Searches erlaubt.

Dabei kann definiert werden, wie weit die gesuchten Begriffe in den Resultaten maximal auseinander liegen dürfen. Wer das Finden von Informationen noch einfacher machen will, kann dies mit Hilfe von frei definierbaren Listen von Stopwörtern, einer Eingrenzung der Wortlänge und Textanalysefunktionen wie Stemming erreichen. Stemming bringt Wörter in ihre Grundform, so dass bei der Suche nach «gelesen» auch Datensätze mit dem Wort «lesen» gefunden werden – allerdings werden diesbezüglich erst die Sprachen Englisch und Russisch unterstützt. Zudem können mit Hilfe von Soundex auch ähnlich klingende Wörter wie «Hahn» und «Bahn» gefunden werden, was eine vereinfachte Form von Googles Funktion «Meinten Sie» darstellt.


Dokumentorientiert

Das Verhalten von Indexer und searchd wird über die zentrale Konfigurationsdatei sphinx.conf geregelt. In ihr werden nicht nur die Datenquellen für den Indexer konfiguriert, sondern unter anderem auch das Stemming oder die zu verwendenden Listen mit Stopwörtern eingestellt.


Sphinx arbeitet mit strukturierten Dokumenten und damit ähnlich wie eine Datenbank, bei der ein Dokument quasi einem Datensatz entspricht, der aus verschiedenen Feldern aufgebaut ist. Dabei wird zwischen Feldern, die indiziert werden, und Attributen unterschieden. Die Attribute dienen dazu, zusätzliche Informationen zu den Datensätzen zu speichern, die zum Einschränken der Suchresultate oder zu deren Sortierung genutzt werden können. Allerdings können Attribute im Moment nur als 32bittige Integer (vorzeichenlos) und UNIX-Timestamps verwendet werden, was aber für die meisten Anwendungen reichen dürfte.



Bei der Speicherung der Attribute kann gewählt werden, ob diese entweder zusammen mit den indizierten Daten oder separat in einer eigenen Datei abgelegt werden sollen. Speichert man sie separat, werden sie von Sphinx beim Start komplett in den RAM geladen und beschleunigen damit die Suche deutlich mehr, als wenn sie zusammen mit den Indices auf Disks liegen. Dies geht aber nur, wenn genügend RAM vorhanden ist, was allerdings bei den heutigen RAM-Preisen weniger ein Problem sein dürfte. Denn mit 4 GB RAM und 4 Attributen liessen sich die Attribute von etwa 200 Millionen Dokumenten laden.


Viele Quellen

Die Indices werden losgelöst von den eigentlichen Daten in mehreren separaten Dateien auf Disk gespeichert. So ist es problemlos möglich, Daten aus verschiedenen Quellen in denselben Index zu integrieren, sofern sie alle gleich strukturiert sind. Als Datenquellen können im Moment nicht nur die relationalen Datenbanksysteme MySQL und PostgreSQL verwendet werden, die über ihre regulären Client-APIs angesprochen werden, sondern alle Arten von Dateien und sogar nicht unterstützte Datenbanken. Für Dateien sowie nicht direkt unterstützte Datenbanken muss man allerdings den Weg über XML gehen, indem man von den einzelnen Datensätzen, die indiziert werden sollen, XML-Dokumente erstellt und sie an das Sphinx-Programm XMLpipe weitergibt. Allerdings ist XMLpipe im Moment noch auf ein bestimmtes XML-Schema beschränkt, an das man sich halten muss, selbst wenn es die gewünschten Funktionen zur Filterung oder Gruppierung von Suchresultaten nur unzureichend abbildet.



Im Falle von MySQL und PostgreSQL werden von Sphinx die Daten wie von einem regulären Client-Programm mit SQL abgefragt. Die Query kann frei gestaltet werden und ermöglicht so beispielsweise, auch komplizierte Berechnungen auszuführen oder Daten aus Views abzufragen, was beispielsweise bei der Volltextsuche von MySQL nicht möglich ist. Welche Daten als Volltextfelder und welche als Attribute behandelt werden sollen, wird per Konfigurationsdirektive geregelt. Es müssen dabei nur zwei Dinge beachtet werden: Jeder Datensatz muss über eine eindeutige ID verfügen, die in einen 32bittigen vorzeichenlosen Integer passt, und es dürfen nicht mehr als 32 Volltextfelder dem Indexer zugeführt werden.
Damit die Indizierung die Datenquellen nicht zu stark belastet, kann Sphinx so konfiguriert werden, dass es die Quellen Schritt für Schritt abfragt, beispielsweise in 100er- oder 1000er- Schritten.


Wer sucht, der findet

Gesucht werden kann, wie bereits erwähnt, entweder über die Kommandozeile mit dem Werkzeug search oder mit Hilfe des Daemons searchd, mit dem über ein Binärprotokoll kommuniziert werden kann. Passende APIs sind unter anderem für PHP, Python, Perl und Ruby vorhanden und können relativ einfach für weitere Sprachen erstellt werden. Eine weitere Möglichkeit ist die Nutzung der Sphinx Storage Engine für MySQL, die selber zwar keine Daten speichert, aber ein Interface in Form einer herkömmlichen Datenbank-Tabelle zum searchd bietet. So ist die Suche für Sprachen einfacher, für die kein Sphinx-API zur Verfügung steht, die aber auf MySQL zugreifen können. Zudem lassen sich weitere Operationen wie JOINs bei der Abfrage der Resultate ausführen.


Findet Sphinx passende Datensätze, werden diese auf der Kommandozeile komplett zurückgeliefert, also auch inklusive Feldern, die ursprünglich nicht zur Erzeugung der Indices verwendet wurden. Wer über die APIs zugreift, muss selber die passenden Daten aus den Quellen fischen. Eine Filterung der Resultate ist mit Hilfe der Attribute möglich, ebenso wie eine Beschränkung der zurückgelieferten Datensätze mit einem variablen Versatz, sodass sich die Suchresultate problemlos auf mehrere Seiten verteilen lassen. Die Sortierung der gefundenen Datensätze ist nach Relevanz, Attributen und Zeit möglich. Zudem können Sortierungsinstruktionen vergleichbar zu SQL zusammengehängt werden («feld1 DESC, feld2 ASC»).
Sollte man mit besonders grossen Indices operieren oder die Suchgeschwindigkeit einem nicht ausreichen, kann man die Arbeit problemlos auf mehrere Rechner verteilen. searchd verteilt dann die Anfragen an die Sphinx-Daemons auf den verschiedenen Rechnern, fasst darauf die erhaltenen Resultate zusammen, wobei Doubletten automatisch entfernt werden, und liefert schliesslich das aggregierte Resultat-Set zurück.





Aufbau von Sphinx




Artikel kommentieren
Kommentare werden vor der Freischaltung durch die Redaktion geprüft.

Anti-Spam-Frage: Wieviele Zwerge traf Schneewittchen im Wald?
GOLD SPONSOREN
SPONSOREN & PARTNER