Die Volltextsuche in MySQL richtig nutzen

Als Web-Entwickler steht man häufiger vor der Herausforderung, eine Volltextsuche in ein PHP-Script zu implementieren, die aus einer Vielzahl an möglichen Treffern nur die wirklich Relavanten herausfiltert. MySQL bietet dafür von Haus aus eine eigene Funktion. Aber auch hier gibt es Gegebenheiten, die beachtet werden müssen. Im Folgenden zeigen wir die Möglichkeiten, die MySQL bietet, um eine entsprechende Abfrage zu erstellen.

Voraussetzungen für die Volltextsuche in MySQL

Um die Volltextsuche von MySQL verwenden zu können bedarf es eines speziellen Indexes, dem sogenanten „FULL TEXT Index“. Ausser einer Ausnahme muss dieser zwingend vergeben werden. Dies geht bis MySQL Version 5.6 nur für Tabellen des Typs MyISAM. Danach ist es jedoch auch mit InnoDB Tabellen möglich, diesen Index zu setzen. Da der FULL TEXT Index nur für Spalten mit dem Datentyp CHAR, VARCHAR oder TEXT angelegt werden kann, kann sich die Volltextsuche auch nur auf Inhalte aus Spalten dieser Typen beziehen. Wir gehen aber hier nicht weiter darauf ein, wie man Schlüssel anlegen kann.

Die Funktionen MATCH() und AGAINST()

MATCH() erwartet eine Kommaseparierte Liste mit allen Spalten, in denen gesucht werden soll, wohingegen AGAINST() den entsprechenden Suchstring erhählt, nach dem gesucht werden soll. Zusätzlich kann man noch einen von drei optionalen Modifizierern anhängen, um den Typ der Suche anzugeben.

Die verschiedenen Typen der Suche

  • IN NATURAL LANGUAGE MODE: Der Suchstring wird hierbei wie ein Satz in natürlicher menschlicher Sprache behandelt. Es gibt keine besonderen Operatoren und die sogenannte Stopwortliste findet hier Anwendung. Das Besondere an diesem Typ: Wörter, die in 50% oder mehr der passenden Datensätze vorkommen, werden als „gewöhnlich“ behandelt und matchen dann nicht mehr.
  • IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION bzw. WITH QUERY EXPANSION: Der Unterschied zu dem vorangegangen Typ ist, dass hierbei Wörter von den am meisten relevanten gefundenen Datensätzen genommen werden und dem Query hinzugefügt werden. Dieser wird dann mit den zusätzlichen Wörter noch einmal automatisch ausgeführt. Der Query liefert also letztendlich die Ergebnisse aus der zweiten Abfrage zurück.
  • IN BOOLEAN MODE: Bei diesem Typ wird der Suchstring mithilfe der Regeln einer speziellen Abfragesprache interpretiert. Der Suchstring kann hier also auch Operatoren enthaten, die z.B. bestimmen, ob ein bestimmes Wort vorkommen muss oder nicht vorkommen darf oder dass es mehr oder weniger gewichtet werden soll

Die Abfrage

Für ein Beispiel nehmen wir an, dass wir eine entsprechende Tabelle mit 2 Spalten des Typs VARCHAR haben, denen wir ein FULLTEXT Index gegeben haben. Im Alltag hat man meist mehr Spalten mit mehr Inhalt. Zur Veranschaulichung soll dies aber reichen:

id name beruf
1 Max Mustermann Schreiner in einer Werkstatt
2 Franz Ferdinand Tischler in einer Tischlerei
3 Klaus Kinski Schauspieler in Hollywood
4 Florian König Berufsmäßiger Schreiner für Möbel
5 Wolfgang Jeschke Schriftsteller für Sci-Fi Literatur
6 Max und Moritz Berufskomiker

Wenn ein Besucher unserer fiktiven Website nun den String „max schreiner“ in ein Suchfeld eingibt, könnte die entsprechende MySQL Abfrage dazu dann folgendermaßen aussehen:

SELECT * FROM kuenstler
WHERE MATCH (name, beruf)
AGAINST ('max schreiner' IN NATURAL LANGUAGE MODE);

Als Ergebnis dieser Abfrage erhalten wir:

id name beruf
1 Max Mustermann Schreiner in einer Werkstatt
6 Max und Moritz Berufskomiker
4 Florian König Berufsmäßiger Schreiner für Möbel

In unserem Fall sind wir mit dem Ergebnis aber nicht zufrieden, da auch Florian König ausgegeben wird, der zwar Schreiner ist, aber eben nicht Max heisst. Ausserdem wurden des Namens wegen auch Max und Moritz gefunden, von denen aber keiner Schreiner ist. Was können wir also tun, um die Qualität der Abfrage zu verbessern ? Wir müssen einen anderen Suchtyp nutzen.

SELECT * FROM kuenstler
WHERE MATCH (name, beruf)
AGAINST ('max schreiner' IN BOOLEAN MODE);

Führen wir die Abfrage so aus, erhalten wir exakt das selbe Ergebnis. Wir müssen das ganze also noch verfeinern. Dafür sind die oben bereits erwähnten Operatoren da. Diese können einfach an die Wörter im Suchstring angehängt werden. Wird ein + an ein Wort angehängt muss es zwingend vorkommen, bei einem – darf es nicht vorkommen. Es gibt noch viele andere Operatoren, aber für unser Beispiel soll dies reichen. Wir benötigen hier nur den + Operator. So sieht nun unsere neue Abfrage aus:

SELECT * FROM kuenstler
WHERE MATCH (name, beruf)
AGAINST ('+max +schreiner' IN BOOLEAN MODE);

Als Ergebnis erhalten wir:

id name beruf
1 Max Mustermann Schreiner in einer Werkstatt

Genau das Ergebnis, welches wir uns wünschen. Wir müssen also in Zukunft nur noch daran denken, den einzelnen Wörtern in unserem Suchstring + Operatoren anzuhängen und fortan werden nur noch die Ergebnisse zurück geliefert, in denen genau diese Wörter enthalten sind. Möchte man die Suche allerdings noch verschärfen und wirklich nur Ergebnisse ausgeben lassen, die exakt den Suchstring enthalten, muss man den String zusätlich noch in Anführungszeichen setzen: ‚“max schreiner“‚. Hier muss man abwägen, wie strikt die Suche sein soll und welche Ergebnisse man erhalten möchte. Sie sollten nun einen guten Überblick über die Möglichkeiten der Volltextsuche in MySQL erhalten haben. Wir wünschen Ihnen wie immer viel Spaß beim Experimentieren.

1 Antwort
  1. BeKu
    BeKu sagte:

    Das ist leider nicht so einfach wie das hier beschrieben wird. Joint man z.B. 2 Tabellen – was ja heute eigentlich Gang und Gäbe ist, und sucht dann, kann man das hier gar nicht so anwenden…auch wird nirgends beschrieben das man Sonderzeichen also z.B. ~“+ usw. maskieren muss wenn man ,,IN BOOLEAN MODE,, nutzt. Macht man das nicht und jemand gibt in das Suchfeld ********** oder ~~~~~~ usw. ein dann gibt es einen 503 Serverfehler.

    Ich bin Anfänger und richtig gute Erklärungen sucht man vergebens, ihr schreibt das für Leute die das schon alles kennen und wissen, ein Anfänger tappt dabei in die Falle weil halt das drumherum verschwiegen wird und man dann vor einem Problem steht und nicht versteht warum es nicht funktioniert den man hat ja alles so geamcht wie ihr es beschrieben habt.

    Darum gibt es hier auch keine Kommentare weil Leute die das wissen lesen sowas nicht oder suchen nicht nach sowas, wer sucht sind Leute die lernen, und dann stößt man auf solche Übershschriften liest probiert und nix geht. Keine Ahnung wem das hier dann nutzen soll, vermutlich nur Googleot.

    Schade.

    Antworten

Dein Kommentar

An Diskussion beteiligen?
Hinterlasse uns Deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert