MySQL 全文檢索
MySQL 從 5.7.6 版開始有內建 ngram,可以支援中文檢索。
SQL 在滿足以下條件時,回傳結果會自動以相關性由高至低排序
以下列出比較有機會用到的運算符:
例如:a 是 stopword
我們要查 'a,b',他會被解析為 'a,'、',b','a,' 會從索引中排除。
又如果我們查 'ai',則會查無結果。
一、事前準備
1. 調整儲存引擎
要使用全文檢索的 table 必須是 InnoDB 或 MyISAM。2. 設定分詞詞語長度
ngram 能對字串進行分詞,每個詞連續 N 個字,N 為 1~10 的數字 (預設為 2),可以在 MySQL 設定檔中進行設定調整。ngram_token_size=2ngram 範例 (全文檢索):
N = 1:全,文,檢,索 N = 2:全文,文檢,檢索 N = 3:全文檢,文檢索 N = 4:全文檢索
二、建立 FULLTEXT 索引
像一般加 index 的方式一樣,建立 FULLTEXT 類型的索引,要注意的是只能在 CHAR、VARCHAR 或 TEXT 的欄位上建立。ALTER TABLE `news` ADD FULLTEXT INDEX ft_index (`title`) WITH PARSER ngram;
WITH PARSER ngram
是重點,一定要有。
三、SQL
全文檢索有三種類型,分別是 Natural Language、Boolean、Query Expansion,MySQL 預設是 Natural Language 也就是我這次用的,以後如果有機會用到其他的再補上來。1. Natural Language
修飾符是IN NATURAL LANGUAGE MODE
,不能使用運算符,由於他是預設類型,所以修飾符寫不寫都沒差。
SQL 在滿足以下條件時,回傳結果會自動以相關性由高至低排序
- 沒有明確的 ORDER BY
- 如果 join 其他 table,全文檢索必須是最左邊的 table
SELECT *, MATCH (`title`) AGAINST ('關鍵字' IN NATURAL LANGUAGE MODE) AS score FROM `news` WHERE MATCH (`title`) AGAINST ('關鍵字' IN NATURAL LANGUAGE MODE);範例中,score 是相關性的評分,搜尋結果就是依據這個評分做排序。
2. Boolean
修飾符是IN BOOLEAN MODE
,可以使用運算符,例如指定關鍵字必須存在或不存在,或它的權重應該比平常高或低。搜尋結果不會按照相關性遞減的順序自動對行進行排序。以下列出比較有機會用到的運算符:
- (無運算符):預設,該關鍵字是可選的,但包含它的結果權重更高。
- +:搜尋結果必須包含有關鍵字。
- -:搜尋結果不包含關鍵字。
- ><:用於更改關鍵字對搜尋結果的權重。>增加權重,<減少權重。
- ():將關鍵字分組為子表達式。
- ~:否定運算符,導致關鍵字對搜尋結果的權重為負。
- *:萬用字元。
SELECT * FROM `news` WHERE MATCH (`title`) AGAINST ('+關鍵字*' IN BOOLEAN MODE);
四、Stopwords
最後還有一個要注意的地方是 stopwords,MySQL 一般在 stopwords 的處理是排除一模一樣的字詞,在 ngram 則是排除包含的字詞。例如:a 是 stopword
我們要查 'a,b',他會被解析為 'a,'、',b','a,' 會從索引中排除。
又如果我們查 'ai',則會查無結果。
留言
張貼留言