Ich habe die drei Zeichenfolgen in Ihrer Frage genommen und sie einer Tabelle hinzugefügt, plus drei weitere Zeichenfolgen mit pankt
anstelle von punkt
.
Folgendes wurde mit MySQL 5.5.12 für Windows ausgeführt
mysql> CREATE TABLE artikel
-> (
-> id INT NOT NULL AUTO_INCREMENT,
-> meldungstext MEDIUMTEXT,
-> PRIMARY KEY (id),
-> FULLTEXT (meldungstext)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO artikel (meldungstext) VALUES
-> ('Punkten'),('Zwei-Punkte-Vorsprung'),('Treffpunkt'),
-> ('Pankten'),('Zwei-Pankte-Vorsprung'),('Treffpankt');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql>
Ich habe diese Abfragen mit drei verschiedenen Ansätzen für die Tabelle ausgeführt
MATCH ... AGAINST
LOCATE
wie in der LOCATE- Funktion
LIKE
Bitte beachten Sie die Unterschiede
mysql> SELECT id,meldungstext,
-> COUNT(IF(MATCH (`meldungstext`) AGAINST ('*punkt*' IN BOOLEAN MODE),1,0)) PunktMatch,
-> IF(LOCATE('punkt',meldungstext)>0,1,0) PunktLocate,
-> meldungstext LIKE '%punkt%' PunktLike
-> FROM `artikel` GROUP BY id,meldungstext;
+----+-----------------------+------------+-------------+-----------+
| id | meldungstext | PunktMatch | PunktLocate | PunktLike |
+----+-----------------------+------------+-------------+-----------+
| 1 | Punkten | 1 | 1 | 1 |
| 2 | Zwei-Punkte-Vorsprung | 1 | 1 | 1 |
| 3 | Treffpunkt | 1 | 1 | 1 |
| 4 | Pankten | 1 | 0 | 0 |
| 5 | Zwei-Pankte-Vorsprung | 1 | 0 | 0 |
| 6 | Treffpankt | 1 | 0 | 0 |
+----+-----------------------+------------+-------------+-----------+
6 rows in set (0.01 sec)
mysql>
Alle PunktMatch-Werte sollten 3 1 und 3 0 sein.
Jetzt schau mir zu, wie ich sie wie gewohnt abfrage
mysql> SELECT `meldungstext` FROM `artikel`
-> WHERE MATCH (`meldungstext`) AGAINST ('*punkt*' IN BOOLEAN MODE);
+-----------------------+
| meldungstext |
+-----------------------+
| Zwei-Punkte-Vorsprung |
| Punkten |
+-----------------------+
2 rows in set (0.01 sec)
mysql> SELECT `meldungstext` FROM `artikel`
-> WHERE LOCATE('punkt',meldungstext)>0;
+-----------------------+
| meldungstext |
+-----------------------+
| Punkten |
| Zwei-Punkte-Vorsprung |
| Treffpunkt |
+-----------------------+
3 rows in set (0.00 sec)
mysql> SELECT `meldungstext` FROM `artikel`
-> WHERE `meldungstext` LIKE '%punk%';
+-----------------------+
| meldungstext |
+-----------------------+
| Punkten |
| Zwei-Punkte-Vorsprung |
| Treffpunkt |
+-----------------------+
3 rows in set (0.00 sec)
mysql>
OK mit MATCH .. GEGEN mit Punkt funktioniert nicht. Was ist mit pankt ???
mysql> SELECT `meldungstext` FROM `artikel` WHERE `meldungstext` LIKE '%pankt%';
+-----------------------+
| meldungstext |
+-----------------------+
| Pankten |
| Zwei-Pankte-Vorsprung |
| Treffpankt |
+-----------------------+
3 rows in set (0.00 sec)
mysql>
Lassen Sie uns meine große GROUP BY
Abfrage gegen pankt ausführen
mysql> SELECT id,meldungstext,
-> COUNT(IF(MATCH (`meldungstext`) AGAINST ('*pankt*' IN BOOLEAN MODE),1,0)) PanktMatch,
-> IF(LOCATE('pankt',meldungstext)>0,1,0) PanktLocate,
-> meldungstext LIKE '%pankt%' PanktLike
-> FROM `artikel` GROUP BY id,meldungstext;
+----+-----------------------+------------+-------------+-----------+
| id | meldungstext | PanktMatch | PanktLocate | PanktLike |
+----+-----------------------+------------+-------------+-----------+
| 1 | Punkten | 1 | 0 | 0 |
| 2 | Zwei-Punkte-Vorsprung | 1 | 0 | 0 |
| 3 | Treffpunkt | 1 | 0 | 0 |
| 4 | Pankten | 1 | 1 | 1 |
| 5 | Zwei-Pankte-Vorsprung | 1 | 1 | 1 |
| 6 | Treffpankt | 1 | 1 | 1 |
+----+-----------------------+------------+-------------+-----------+
6 rows in set (0.01 sec)
mysql>
Dies ist auch falsch, weil ich 3 0er und 3 1er für PanktMatch sehen sollte.
Ich habe etwas anderes versucht
mysql> SELECT id,meldungstext, MATCH (`meldungstext`) AGAINST ('+*pankt*' IN BOOLEAN MODE) PanktMatch, IF(LOCATE('pankt',meldungstext)>0,1,0) PanktLocate, meldungstext LIKE '%pankt%' PanktLike FROM `artikel` GROUP BY id,meldungstext;
+----+-----------------------+------------+-------------+-----------+
| id | meldungstext | PanktMatch | PanktLocate | PanktLike |
+----+-----------------------+------------+-------------+-----------+
| 1 | Punkten | 0 | 0 | 0 |
| 2 | Zwei-Punkte-Vorsprung | 0 | 0 | 0 |
| 3 | Treffpunkt | 0 | 0 | 0 |
| 4 | Pankten | 1 | 1 | 1 |
| 5 | Zwei-Pankte-Vorsprung | 1 | 1 | 1 |
| 6 | Treffpankt | 0 | 1 | 1 |
+----+-----------------------+------------+-------------+-----------+
6 rows in set (0.00 sec)
mysql>
Ich habe pankt ein Pluszeichen hinzugefügt und unterschiedliche Ergebnisse erzielt. Welche 2 und nicht 3 ???
Beachten Sie gemäß der MySQL-Dokumentation , was darin über das Platzhalterzeichen steht:
* *
Das Sternchen dient als Kürzungs- (oder Platzhalter-) Operator. Im Gegensatz zu den anderen Operatoren sollte es an das betroffene Wort angehängt werden. Wörter stimmen überein, wenn sie mit dem Wort vor dem Operator * beginnen.
Wenn ein Wort mit dem Kürzungsoperator angegeben wird, wird es nicht aus einer booleschen Abfrage entfernt, auch wenn es zu kurz (wie aus der Einstellung ft_min_word_len bestimmt) oder ein Stoppwort ist. Dies liegt daran, dass das Wort nicht als zu kurz oder als Stoppwort angesehen wird, sondern als Präfix, das im Dokument in Form eines Wortes vorhanden sein muss, das mit dem Präfix beginnt. Angenommen, ft_min_word_len = 4. Dann wird eine Suche nach '+ Wort + das *' wahrscheinlich weniger Zeilen zurückgeben als eine Suche nach '+ Wort + das':
Die vorherige Abfrage bleibt unverändert und erfordert, dass sowohl das Wort als auch das * (ein Wort, das mit dem beginnt) im Dokument vorhanden sind.
Die letztere Abfrage wird in + Wort umgewandelt (wobei nur Wort vorhanden sein muss). Das ist sowohl zu kurz als auch ein Stoppwort, und jede Bedingung reicht aus, um es zu ignorieren.
Auf dieser Grundlage gilt das Platzhalterzeichen für die Rückseite von Token und nicht für die Vorderseite. Vor diesem Hintergrund muss die Ausgabe korrekt sein, da 2 der 3 Punkt-Start-Token vorhanden sind. Gleiche Geschichte mit pankt. Dies erklärt zumindest, warum 2 von 3 und warum weniger Zeilen.