1. 程式人生 > >Mysql全文搜尋之MATCH...AGAINST的用法介紹

Mysql全文搜尋之MATCH...AGAINST的用法介紹

前提:mysql只支援英文內容的全文索引,所以只考慮英文的全文搜尋。假定資料表名為post,有三列:id、title、content。id是自增長序號,title是varchar,content是text,給content新增全文索引。

mysql全文搜尋有三種模式:

一、自然語言查詢。這是mysql預設的全文搜尋方式,sql示例:

select  id,title FROM post WHERE MATCH(content) AGAINST ('search keyword')

或者顯式宣告使用自然語言搜尋方式
 select  id,title FROM post WHERE MATCH(content) AGAINST ('search keyword' IN NATURAL LANGUAGE MODE)


由於自然語言搜尋方式是預設模式,所以可以省略宣告模式的“IN NATURAL LANGUAGE MODE”部分。
自然語言搜尋模式的麼特點:

    1.忽略停詞(stopword),英語中頻繁出現的and/or/to等詞被認為是沒有實際搜尋的意義,搜尋這些不會獲得任何結果。
    2.如果某個詞在資料集中頻繁出現的機率超過了50%,也會被認為是停詞,所以如果資料庫中只有一行資料,不管你怎麼全文搜尋都不能獲得結果。
    3.搜尋結果都具有一個相關度的資料,返回結果自動按相關度由高到低排列。
    4.只針對獨立的單詞進行檢索,而不考慮單詞的區域性匹配,如搜尋box時,就不會將boxing作為檢索目標。


二、布林查詢。這種查詢方式的特點是沒有自然查詢模式中的50%規則,即便有詞語在資料集中頻繁出現的機率超過50%,也會被作為搜尋目標進行檢索並返回結果,而且檢索時單詞的區域性匹配也會被作為目標進行檢索。sql示例
select  id,title FROM post WHERE MATCH(content) AGAINST ('search keyword' IN BOOLEAN MODE)

三、帶子查詢擴充套件的自然語言查詢。
select  id,title FROM post WHERE MATCH(content) AGAINST ('search keyword' IN BOOLEAN MODE WITH EXPANSION)

暫時沒有明白這種模式。
四、布林全文搜尋支援以下操作符:

    " + "  一個前導的加號表示該單詞必須 出現在返回的每一行的開頭位置
    " - " 一個前導的減號表示該單詞一定不能出現在任何返回的行中
    (無操作符) 在預設狀態下(當沒有指定 + 或–的情況下),該單詞可有可無,但含有該單詞的行等級較高。這和MATCH() ... AGAINST()不使用IN BOOLEAN MODE修改程式時的運作很類似
    " > < "這兩個操作符用來改變一個單詞對賦予某一行的相關值的影響。 >操作符增強其影響,而 <操作符則減弱其影響。請參見下面的例子
    " () "括號用來將單詞分成子表示式。括入括號的部分可以被巢狀
    " ~ "一個前導的代字號用作否定符, 用來否定單詞對該行相關性的影響。 這對於標記“noise(無用資訊)”的單詞很有用。包含這類單詞的行較其它行等級低,但因其可能會和-號同時使用,因而不會在任何時候都派出所有無用資訊行
    " * "星號用作截斷符。於其它符號不同的是,它應當被追加到要截斷的詞上
    " " "一個被括入雙引號的短語 (‘"’) 只和字面上包含該短語輸入格式的行進行匹配。全文引擎將短語拆分成單詞,在FULLTEXT索引中搜索該單詞。  非單詞字元不需要嚴密的匹配:短語搜尋只要求符合搜尋短語包含的單詞且單詞的排列順序相同的內容。例如, "test phrase" 符合 "test, phrase"。
    "configured database "尋找包含至少兩個單詞中的一個的行
    " +configured +database "尋找兩個單詞都包含的行
    " +configured database "尋找包含單詞“"configured”的行,若這些行也包含單詞“"database”, 則列為更高等級
    " +configured -database "尋找包含單詞“configured” 但不包含單詞 “database”的行
    " +configured +(>database<sql) "尋找包含單詞“configured”和“database” 的行,或包含“configured” 和“sql”的行 (無先後順序),然而包含 “configured database”的行較包含“configured sql”的行排列等級更為高
    " mysql* "尋找包含"mysql"或有"mysql"開頭單詞的行
    " “my sql” "尋找包含原短語“my sql”的行

如:

select * from info where match(title,info) against("+mysql -yoursql" in boolean mode);
select * from info where match(title,info) against('+configured +database');

在我的實際使用中還發現了以下細節:
1、只有MyISAM表支援
    2、對大多數的多位元組字符集適用,進行全文索引的列必須使用相同的字符集和校驗碼(collation)。
    3、表意性語言,如漢語、日語沒有詞分界符(英語用空格隔開每個單詞),全文分析器無法確定一個詞的開始和結尾,所以MySQL中的全文檢索不支援。
    4、在自然語言檢索中,只能檢索被全文索引的那些列,如果要對索引的多列進行某一列的檢索,必須對這一列單獨建立全文索引。布林檢索可以在非索引的列上進行,但會慢一些。
    5、against後的引數必須是常量字串。
    6、索引沒有記錄關鍵詞在字串中的位置,排序演算法太單一。
    7、如果索引不在記憶體中,檢索速度會很慢;如果是短語查詢,需要索引和資料都在記憶體中,否則速度會很慢,所以需要更大的key buffer。索引有碎片時也會很慢,所以需要更頻繁的optimize table操作。
    8、全文索引對於insert、update、delete都很慢。如更改100個詞需要進行100次的索引操作而不是1次。
    9.布林查詢時必須指定返回結果的排序方式,它不會像自然語言查詢那樣會自動將結果按相關度排序返回。
    10.即使是布林查詢,對長度小於等於3的單詞也不會進行檢索,因為mysql有一個系統變數FT_MIN_WORD_LEN指定了全文檢索時可接受的最小單詞長度,預設值是4。.