mysql全文檢索

 

http://androider.javaeye.com/blog/643486

 

mysql到版本3.23.23時,開始支持全文檢索,通過語句SELECT ... FROM ... MATCH(...)AGAINST(...)來在整個表中檢索是否有匹配的,全文索引是一個定義爲fulltext的類型索引,應用在myisam表中。值得一提的是對於一個大的數據庫來說,把數據裝載到一個沒有fulltext索引的表中,然後再添加索引,這樣速度會非常快,但是把數據裝載到一個已經有fulltext索引的表中,這樣速度非常慢的。

 

首頁要先明白mysql的全文檢索原理:mysql使用的是一個非常簡單的剖析器來將文本分隔成詞,空格、標點等,比如‘welcomtoyou’將分隔爲三個詞‘welcom’、‘to’、‘you’,但是對中文來說,比如‘人力方網站正式上線’,這將無法分隔,因此目前mysql只支持英文的全文檢索。

 

下面我們通過實例來一步步把全文檢索的過程解釋清楚:

首頁我們建立表與初始化數據

Sql代碼 複製代碼
  1. CREATE TABLE IF NOT EXISTS `category` (      
  2.   `id` int(10) NOT NULL auto_increment,      
  3.   `fid` int(10) NOT NULL,      
  4.   `catname` char(255) NOT NULL,      
  5.   `addtime` char(10) NOT NULL,      
  6.   PRIMARY KEY  (`id`),      
  7.   FULLTEXT KEY `catname` (`catname`)      
  8. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;      
  9.      
  10.      
  11. INSERT INTO `category` (`id`, `fid`, `catname`, `addtime`) VALUES     
  12. (1, 0, 'welcome to you!''1263363380'),      
  13. (2, 0, 'hello phpjs,you are welcome''1263363416'),      
  14. (3, 0, 'this is the fan site of you''1263363673');     
  15.    
 

在具體實例之前,我們分析下msyql全文檢索的語法:函數 MATCH() 對照一個文本集(包含在一個 FULLTEXT索引中的一個或多個列的列集)執行一個自然語言搜索一個字符串。搜索字符串做爲 AGAINST()的參數被給定。搜索以忽略字母大小寫的方式執行。說白了就是MATCH給定匹配的列(fulltext類型索引),AGAINST給定要匹配的字符串,多個用空格、標點分開,mysql會自動分隔。

1、

SQL代碼
  1. SELECT * FROM `category` WHERE MATCH(catname) AGAINST('phpjs')  

 

返回結果:

id  fid catname                                addtime  
2  0   hello phpjs,you are welcome 1263363416

匹配出了含有phpjs關鍵字的行數據。

 

2、

SQL代碼
  1. SELECT * FROM `category` WHERE MATCH (catname) AGAINST ('this')  

 

按照上面的思路,第三行數據含有this,因此應該可以匹配出第三行數據的,但事實卻奇怪得很,返回結果爲空,爲什麼呢?

原來是mysql指定了最小字符長度,默認是4,必須要匹配大於4的纔會有返回結果,可以用SHOW VARIABLESLIKE'ft_min_word_len'來查看指定的字符長度,也可以在mysql配置文件my.ini 更改最小字符長度,方法是在my.ini 增加一行比如:ft_min_word_len = 2,改完後重啓mysql即可。

 

3、這裏我們要確定把最小字符改爲2了,因爲3行記錄都有‘you’,因此心想,匹配‘you’就可以返回所有結果了

SQL代碼
  1. SELECT * FROM `category` WHERE MATCH (catname) AGAINST ('you')  
 

返回結果還是爲空,大跌眼鏡了吧,這又是爲什麼呢?

原來mysql在集和查詢中的對每個合適的詞都會先計算它們的權重,一個出現在多個文檔中的詞將有較低的權重(可能甚至有一個零權重),因爲在這個特定的集中,它有較低的語義值。否則,如果詞是較少的,它將得到一個較高的權重,mysql默認的閥值是50%,上面‘you’在每個文檔都出現,因此是100%,只有低於50%的纔會出現在結果集中。

 

4、有人會想,我不去管權重大小,只要有匹配的就給我返回結果集中,那麼該如何做呢?

mysql到 4.0.1 時,可以使用 IN BOOLEAN MODE 修飾語來執行一個邏輯全文搜索

SQL代碼
  1. SELECT * FROM `category` WHERE MATCH(catname) AGAINST('you' IN BOOLEAN MODE)  

 

 

總結:1、要注意最小字符的長度;

          2、要注意關鍵詞的權重;

 

ps,一些學習資料:

http://www.111cn.net/database/110/FULLTEXT-mysql.htm

 

http://onlamp.com/pub/a/onlamp/2003/06/26/fulltext.html

 

http://dev.mysql.com/doc/refman/5.1/zh/functions.html#fulltext-query-expansion


發佈了3 篇原創文章 · 獲贊 7 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章