Tôi lấy ba chuỗi trong câu hỏi của bạn và thêm nó vào một bảng cộng với ba chuỗi nữa pankt
thay vì punkt
.
Sau đây đã được thực hiện bằng MySQL 5.5.12 cho 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>
Tôi đã chạy các truy vấn này trên bảng bằng 3 cách tiếp cận khác nhau
MATCH ... AGAINST
LOCATE
như trong hàm LOCATE
LIKE
Xin lưu ý sự khác biệt
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>
Tất cả các giá trị PunktMatch nên tạo ra 3 1 và 3 0.
Bây giờ hãy xem tôi truy vấn họ như bình thường
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 sử dụng MATCH .. LẠI với punkt không hoạt động. Thế còn pankt ???
mysql> SELECT `meldungstext` FROM `artikel` WHERE `meldungstext` LIKE '%pankt%';
+-----------------------+
| meldungstext |
+-----------------------+
| Pankten |
| Zwei-Pankte-Vorsprung |
| Treffpankt |
+-----------------------+
3 rows in set (0.00 sec)
mysql>
Hãy chạy GROUP BY
truy vấn lớn của tôi chống lại 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>
Điều này cũng sai vì tôi sẽ thấy 3 0 và 3 1 cho PanktMatch.
Tôi đã thử một cái gì đó khác
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>
Tôi đã thêm một dấu cộng cho pankt và tôi đã nhận được kết quả khác nhau. Cái gì 2 chứ không phải 3 ???
Theo Tài liệu MySQL , hãy chú ý những gì nó nói về ký tự đại diện:
*
Dấu hoa thị đóng vai trò là toán tử cắt (hoặc ký tự đại diện). Không giống như các toán tử khác, nó nên được thêm vào từ bị ảnh hưởng. Các từ khớp với nhau nếu chúng bắt đầu bằng từ đứng trước toán tử *.
Nếu một từ được chỉ định với toán tử cắt bớt, nó không bị tước khỏi truy vấn boolean, ngay cả khi nó quá ngắn (như được xác định từ cài đặt ft_min_word_len) hoặc từ khóa. Điều này xảy ra bởi vì từ này không được xem là quá ngắn hoặc một từ dừng, mà là một tiền tố phải có trong tài liệu dưới dạng một từ bắt đầu bằng tiền tố. Giả sử rằng ft_min_word_len = 4. Sau đó, tìm kiếm '+ word + the *' có thể sẽ trả về ít hàng hơn so với tìm kiếm '+ word + the':
Truy vấn cũ vẫn giữ nguyên và yêu cầu cả từ và * (một từ bắt đầu bằng) phải có trong tài liệu.
Truy vấn sau được chuyển thành + từ (chỉ yêu cầu phải có mặt). cả hai quá ngắn và một từ khóa, và một trong hai điều kiện là đủ để làm cho nó bị bỏ qua.
Dựa trên điều này, ký tự đại diện được áp dụng cho mặt sau của mã thông báo chứ không phải cho mặt trước. Theo cách này, đầu ra phải chính xác vì 2 trong số 3 mã thông báo bắt đầu của punkt. Câu chuyện tương tự với pankt. Điều này ít nhất giải thích tại sao 2 trên 3 và tại sao ít hàng hơn.