全文檢索FTS不同於模糊查詢like,它可以匹配局部的查詢條件,即把原查詢條件做下分詞再去查詢。
比如查詢條件是:food fruit
,全文檢索可以做到返回 包含 food fruit
,food
, fruit
, fruit food
的結果集。
不僅如此,MySQL通過Boolean FTS
還可以做到查詢結果包含 food
但不包含 fruit
。
MySQL全文檢索概述
- 目前MySQL支持
FULLTEXT
index的存儲引擎是InnoDB
和MyISAM
; FULLTEXT
index的column列類型只支持:CHAR, VARCHAR, or TEXT
;FULLTEXT
index 只有在查詢語句使用MATCH() AGAINST()
時候才會生效;
創建 Full-Text Search
MySQL FTS需要創建 FULLTEXT
類型的 index,index要包含所有想要全文檢索的列。
創建FTS語法:
CREATE TABLE table_name(
column_list,
...,
FULLTEXT (column1,column2,..)
);
ALTER TABLE table_name
ADD FULLTEXT(column_name1, column_name2,…)
CREATE FULLTEXT INDEX index_name
ON table_name(idx_column_name,...)
刪除FTS語法:
ALTER TABLE table_name
DROP INDEX index_name;
創建full-text index 示例:
create fulltext index full_idx_name_author_publisher
on book(name, author, publisher);
MySQL默認的 full-text parser
根據單詞間的空格或空白符來分割單詞的;但這對於表意語言如中文、韓語和日本語就沒作用了。
為了解決這個問題,MySQL提供了ngram full-text parser
,從5.76開始,MySQL把ngram full-text parser
作為server內置插件。
create fulltext index full_idx_name_author_publisher
on book(name, author, publisher) WITH PARSER NGRAM;
注意: 實際使用 ngram parser
的時候,需要關注 stopwords
,最好自定義相關語言的 stop word
列表。
MySQL FTS檢索
MySQL全文檢索類型:
- natural language search type
- boolean search type
- query expansion search type
Natural-Language檢索
select * from book
where
match(name, author, publisher) -- 想要匹配的column列表,需要和創建index時候的column列表一致:列名和個數要一樣(順序可以不一樣),不然sql會報錯。
against('北京日報') -- 關鍵字
或
select * from book
where
match(publisher,name, author)
against('北京日報' IN NATURAL LANGUAGE MODE);
- 如果查詢的是中文,創建index的時候要指定用
ngram parser
; - match的column列表需要和創建index時候的column列表一致:列名和個數要一樣(順序可以不一樣),不然sql會報錯;
IN NATURAL LANGUAGE MODE
是可選項,因為它是默認檢索類型。
Boolean FTS
select * from book
where
match(publisher,name, author)
against('北京日報 -青鳥' IN BOOLEAN MODE);
Boolean操作符:
+
: Include, the word must be present.–
: Exclude, the word must not be present.>
: Include, and increase ranking value.<
: Include, and decrease the ranking value.()
: Group words into subexpressions (allowing them to be included, excluded, ranked, and so forth as a group).~
: Negate a word’s ranking value.*
: Wildcard at the end of the word.“”
: Defines a phrase (as opposed to a list of individual words, the entire phrase is matched for inclusion or exclusion).
Query Expansion
select * from book
where
match(publisher,name, author)
against('老舍' WITH QUERY EXPANSION);
- 先查出匹配關鍵字的結果集
- 從結果集里獲取相關詞匯
- 用相關詞匯做為條件再次查詢
注意:可能會查出很多不相關的結果。