MySQL全文字搜尋 擴充套件搜尋 布林搜尋 FULLTEXT
總結:
- 全文字搜尋Match(FULLTEXT) Against(‘text’)。注意FULLTEXT索引要在導完資料後再定義FULLTEXT是哪(些)列,否則很耗時。
- 全文字搜尋結果輸出會按相關性排列。
- 擴充套件查詢Against(‘text’ WITH QUERY EXPANSION):可查到更多輸入關鍵詞相關的行,但是有可能會增加很多不需要的行。
- 布林文字搜尋Against(‘text’ IN BOOLEAN MODE):可排斥不包含這個詞的行;按某種順序排列;表示式分組等。沒有FULLTEXT索引也可以用,但效能隨資料量增加而降低;全文字布林操作符。排列而不排序。
- 忽略詞:字元長度<3;stopword;高頻詞(>50%);錶行數<3;單引號。
- 沒有分隔詞的語言不適用全文字搜尋,如漢語日語。
- 只有MyISAM支援全文字搜尋。
兩個最常使用引擎:InnoDB和MyISAM
其中,InnoDB不支援全文字搜尋。只有MyISAM支援,注意!
LIKE萬用字元只能匹配已知包含此文字的行,正則化匹配可查詢更加複雜的匹配模式。
但LIKE萬用字元和正則化匹配仍存在一些限制:
- 匹配表中所有行,非常耗時;
- 很難明確匹配或不匹配什麼;
- 不太智慧,如不能返回與搜尋詞相關的此,不區分包括單個匹配的行或包括多個匹配的行,以及排序等問題,
全文字搜尋可解決上述限制。建立FULLTEXT索引,提高效率。
1. 利用全文字搜尋 Match(index) Against(text)查詢:
傳遞給Match()的值必須與FULLTEXT()中的相同,即Match括號中必須是FULLTEXT,即有索引的列。如果要指定多列,需要按順序列出。
SELECT note_text FROM productnotes WHERE Match(note_text) Against('rabbit');
2. 用WHERE
SELECT note_text FROM productnotes WHERE note_text LIKE '%rabbit%';
3. 輸出等級,並按相關等級高低排序
SELECT note_text,Match(note_text) Against('rabbit') as ranks FROM productnotes ORDER BY ranks DESC;
4. 查詢擴充套件
4.1 用簡單的WHERE LIKE,只有1條結果
SELECT note_text FROM productnotes WHERE note_text LIKE '%anvils%';
4.2 使用查詢擴充套件
有7行結果,但其實只有第一行包含了anvils這個詞,其他行不包括。但第二行包含了第一行的兩個詞:customer和recommend。
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('anvils' WITH QUERY EXPANSION);
評估查詢擴充套件:返回的行越多,擴充套件查詢越好,但同時也增加了不想要的行。
5. 布林文字搜尋:
布林方式(Boolean mode),沒有FULLTEXT索引也可以用,但是操作很慢。
瞭解掌握不同布林操作符的含義。
表來自《MySQL必知必會》第18章
5.1 包含rabbit或bait的行
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('rabbit bait' IN BOOLEAN MODE);
5.2 - *
包含heavy,且不包含所有有rope開頭的詞的行:
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('heavy -rope*' IN BOOLEAN MODE);
5.3 +
必須包含rabbit和bait的行
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('+rabbit +bait' IN BOOLEAN MODE);
5.4 “”
包括短語“rabbit bait”的行
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('"rabbit bait"' IN BOOLEAN MODE);
5.5 ><增加或降低等級
匹配rabbit和carrot,增加前者等級,降低後者等級
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('>rabbit <carrot' IN BOOLEAN MODE);
5.6 ()
降低後者等級
SELECT note_text FROM productnotes
WHERE Match(note_text) Against('+safe +(<combination)' IN BOOLEAN MODE);
6. 全文字搜尋的使用說明
- <=3個字元短詞被忽略。
- 內建非用詞(stopword)被忽略。
- 高頻詞(>50%,即出現在50%以上的行中)被忽略。(IN BOOLEAN MODE)除外。
- 表中行數<3,即只要1或2行的表,全文字搜尋不返回結果。
- 忽略單引號。如don’t索引為don’t。
- 不具有詞分隔詞的語言不適用(如日語漢語)。
- 僅在MyISAM資料庫中支援全文字搜尋。