J'ai pris les trois chaînes dans votre question et je l'ai ajouté à un tableau plus trois autres chaînes avec pankt
au lieu de punkt
.
Ce qui suit a été exécuté à l'aide de MySQL 5.5.12 pour Windows
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>
J'ai exécuté ces requêtes sur la table en utilisant 3 approches différentes
MATCH ... AGAINST
LOCATE
comme dans la fonction LOCATE
LIKE
Veuillez noter les différences
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>
Toutes les valeurs de PunktMatch doivent être de 3 1 et 3 0.
Maintenant, regardez-moi les interroger comme d'habitude
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 en utilisant MATCH .. CONTRE avec punkt ne fonctionne pas. Et pankt ???
mysql> SELECT `meldungstext` FROM `artikel` WHERE `meldungstext` LIKE '%pankt%';
+-----------------------+
| meldungstext |
+-----------------------+
| Pankten |
| Zwei-Pankte-Vorsprung |
| Treffpankt |
+-----------------------+
3 rows in set (0.00 sec)
mysql>
GROUP BY
Lançons ma grande requête contre pankt
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>
C'est faux aussi parce que je devrais voir 3 0 et 3 1 pour PanktMatch.
J'ai essayé autre chose
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>
J'ai ajouté un signe plus à pankt et j'ai obtenu des résultats différents. Que 2 et non 3 ???
Selon la documentation MySQL , notez ce qu'il dit sur le caractère générique:
*
L'astérisque sert d'opérateur de troncature (ou de caractère générique). Contrairement aux autres opérateurs, il doit être ajouté au mot à affecter. Les mots correspondent s'ils commencent par le mot précédant l'opérateur *.
Si un mot est spécifié avec l'opérateur de troncature, il n'est pas supprimé d'une requête booléenne, même s'il est trop court (comme déterminé à partir du paramètre ft_min_word_len) ou d'un mot d'arrêt. Cela se produit car le mot n'est pas considéré comme trop court ou un mot d'arrêt, mais comme un préfixe qui doit être présent dans le document sous la forme d'un mot qui commence par le préfixe. Supposons que ft_min_word_len = 4. Ensuite, une recherche de '+ mot + le *' retournera probablement moins de lignes qu'une recherche de '+ mot + le':
L'ancienne requête reste telle quelle et requiert que le mot et le * (un mot commençant par le) soient présents dans le document.
Cette dernière requête est transformée en + mot (ne nécessitant que le mot pour être présent). le est à la fois trop court et un mot d’arrêt, et l’une ou l’autre condition suffit pour qu’elle soit ignorée.
Sur cette base, le caractère générique est applicable pour le dos des jetons et non pour le devant. À la lumière de cela, la sortie doit être correcte car 2 des 3 jetons de démarrage du punkt. Même histoire avec pankt. Cela explique au moins pourquoi 2 sur 3 et pourquoi moins de lignes.