Wziąłem trzy ciągi z twojego pytania i dodałem je do tabeli plus trzy kolejne z pankt
zamiast punkt
.
Poniższe czynności zostały wykonane przy użyciu MySQL 5.5.12 dla systemu 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>
Uruchomiłem te zapytania do tabeli przy użyciu 3 różnych podejść
MATCH ... AGAINST
LOCATE
jak w funkcji LOCATE
LIKE
Zwróć uwagę na różnice
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>
Wszystkie wartości PunktMatch powinny być równe 3 1 i 3 0.
Teraz patrz, jak pytam o nie jak zwykle
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 przy użyciu funkcji PODAJ. PONOWNIE z punktem nie działa. A co z panktem ???
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
Uruchommy moje duże zapytanie przeciwko 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>
Jest to również złe, ponieważ powinienem zobaczyć 3 0 i 3 1 dla PanktMatch.
Próbowałem czegoś innego
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>
Dodałem znak plus do pankt i uzyskałem różne wyniki. Co 2, a nie 3 ???
Zgodnie z Dokumentacją MySQL zwróć uwagę na to, co mówi o znaku wieloznacznym:
*
Gwiazdka służy jako operator obcięcia (lub symbolu wieloznacznego). W przeciwieństwie do innych operatorów, należy dodać do słowa, którego dotyczy zmiana. Słowa pasują, jeśli zaczynają się od słowa poprzedzającego operator *.
Jeśli słowo zostanie określone za pomocą operatora obcięcia, nie jest usuwane z zapytania boolowskiego, nawet jeśli jest ono zbyt krótkie (jak określono w ustawieniu ft_min_word_len) lub słowo kluczowe. Dzieje się tak, ponieważ słowo nie jest postrzegane jako zbyt krótkie lub słowo kluczowe, ale jako przedrostek, który musi występować w dokumencie w formie słowa rozpoczynającego się od przedrostka. Załóżmy, że ft_min_word_len = 4. Wtedy wyszukiwanie „+ słowo + słowo *” prawdopodobnie zwróci mniej wierszy niż wyszukiwanie „+ słowo + słowo”:
Poprzednie zapytanie pozostaje takie, jakie jest i wymaga, aby zarówno słowo, jak i * (słowo zaczynające się od) były obecne w dokumencie.
To ostatnie zapytanie jest przekształcane na słowo + (wymagające obecności tylko słowa). jest zarówno zbyt krótki, jak i słowo-stop, a każdy z warunków wystarcza, aby go zignorować.
Na tej podstawie znak wieloznaczny ma zastosowanie do tyłu znaczników, a nie do przodu. W świetle tego wynik musi być poprawny, ponieważ 2 z 3 żetonów początkowych punktu. Ta sama historia z panktem. To przynajmniej wyjaśnia, dlaczego 2 z 3 i dlaczego mniej wierszy.