ผมเอาสามสายในคำถามของคุณและเพิ่มไปยังตารางบวกสตริงสามมากขึ้นด้วยการแทนpankt
punkt
ต่อไปนี้ถูกดำเนินการโดยใช้ MySQL 5.5.12 สำหรับ 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>
ฉันใช้คำสั่งเหล่านี้เทียบกับตารางโดยใช้วิธีการ 3 แบบ
MATCH ... AGAINST
LOCATE
เช่นเดียวกับในฟังก์ชั่นLOCATE
LIKE
โปรดทราบความแตกต่าง
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>
ค่า PunktMatch ทั้งหมดควรเก็บค่า 3 1 และ 3 0
ตอนนี้ดูฉันค้นหาพวกเขาตามปกติ
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>
ตกลงใช้ MATCH .. เทียบกับ punkt ไม่ทำงาน 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
คิวรีขนาดใหญ่กับ 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>
นี่เป็นสิ่งที่ผิดด้วยเพราะฉันควรเห็น PanktMatch 3 0 และ 3 1
ฉันลองอย่างอื่น
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>
ฉันเพิ่มเครื่องหมายบวกไปที่ pankt และฉันได้ผลลัพธ์ที่แตกต่างกัน อะไรที่ 2 และไม่ใช่ 3 ???
ตามเอกสาร MySQLให้สังเกตสิ่งที่พูดเกี่ยวกับอักขระตัวแทน:
* * * *
เครื่องหมายดอกจันทำหน้าที่เป็นตัวดำเนินการที่ถูกตัดทอน (หรือไวด์การ์ด) ซึ่งแตกต่างจากผู้ประกอบการอื่น ๆ มันควรจะผนวกเข้ากับคำที่จะได้รับผลกระทบ คำที่ตรงกันหากพวกเขาเริ่มต้นด้วยคำก่อนหน้าผู้ประกอบการ *
หากมีการระบุคำด้วยตัวดำเนินการตัดคำนั้นจะไม่ถูกแยกออกจากคิวรีบูลีนแม้ว่าจะสั้นเกินไป (ตามที่กำหนดจากการตั้งค่า ft_min_word_len) หรือคำหยุด สิ่งนี้เกิดขึ้นเนื่องจากคำไม่ถูกมองว่าสั้นเกินไปหรือคำหยุด แต่เป็นคำนำหน้าที่ต้องมีอยู่ในเอกสารในรูปแบบของคำที่ขึ้นต้นด้วยคำนำหน้า สมมติว่า ft_min_word_len = 4 จากนั้นการค้นหา '+ คำ + the *' จะส่งกลับแถวน้อยกว่าการค้นหา '+ word + the':
แบบสอบถามแบบเดิมยังคงเป็นอยู่และต้องการทั้งคำและ * (คำที่ขึ้นต้นด้วย) เพื่อให้ปรากฏในเอกสาร
แบบสอบถามหลังถูกแปลงเป็นคำ + (ต้องการคำเท่านั้นที่จะมีอยู่) สั้นเกินไปและเป็นคำหยุดและเงื่อนไขอย่างใดอย่างหนึ่งก็เพียงพอที่จะทำให้มันถูกละเว้น
ขึ้นอยู่กับสิ่งนี้อักขระ wildcard นั้นใช้กับด้านหลังของโทเค็นและไม่ใช่สำหรับด้านหน้า ด้วยเหตุนี้ผลลัพธ์จะต้องถูกต้องเนื่องจากโทเค็นเริ่มต้นของพังก์ 2 ใน 3 ตัว เรื่องเดียวกันกับ pankt อย่างน้อยก็อธิบายว่าทำไม 2 จาก 3 และทำไมจำนวนแถวน้อยลง