mysql全文搜索 sql命令的寫(xiě)法
更新時(shí)間:2011年01月03日 14:31:47 作者:
首先,大家先去下載一份dvbbs.php beta1的代碼,解壓后先拋開(kāi)php代碼,找出你的mysql手冊(cè),如果沒(méi)有手冊(cè)那么就直接看下面的實(shí)例操作吧!
mysql全文搜索,sql的寫(xiě)法:
MATCH (col1,col2,…) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION])
比如:
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');
MATCH()函數(shù)對(duì)于一個(gè)字符串執(zhí)行資料庫(kù)內(nèi)的自然語(yǔ)言搜索。一個(gè)資料庫(kù)就是1套1個(gè)或2個(gè)包含在FULLTEXT內(nèi)的列。搜索字符串作為對(duì) AGAINST()的參數(shù)而被給定。對(duì)于表中的每一行, MATCH() 返回一個(gè)相關(guān)值,即, 搜索字符串和 MATCH()表中指定列中該行文字之間的一個(gè)相似性度量。
下面的例子則更加復(fù)雜。詢(xún)問(wèn)返回相關(guān)值,同時(shí)對(duì)行按照相關(guān)性漸弱的順序進(jìn)行排序。為實(shí)現(xiàn)這個(gè)結(jié)果,你應(yīng)該兩次指定 MATCH(): 一次在 SELECT 列表中而另一次在 WHERE子句中。這不會(huì)引起額外的內(nèi)務(wù)操作,原因是MySQL 優(yōu)化程序注意到兩個(gè)MATCH()調(diào)用是相同的,從而只會(huì)激活一次全文搜索代碼。
mysql> SELECT id, body, MATCH
(title,body) AGAINST
-> ('Security implications of
running MySQL as root') AS score
-> FROM articles WHERE MATCH
(title,body) AGAINST
-> ('Security implications of
running MySQL as root');
所以,到這里你應(yīng)該會(huì)mysql 英文全文搜索了.
請(qǐng)注意一個(gè)問(wèn)題.
一些詞在全文搜索中會(huì)被忽略:
* 任何過(guò)于短的詞都會(huì)被忽略。 全文搜索所能找到的詞的默認(rèn)最小長(zhǎng)度為 4個(gè)字符。
* 停止字中的詞會(huì)被忽略。
mysql還自帶查詢(xún)擴(kuò)展功能.這里不做過(guò)多討論.
下面進(jìn)行php中文全文搜索的分析
曾經(jīng)有一個(gè)版本的mysql支持中文全文搜索(海量 mysql chinese+,說(shuō)是GPL但是最終沒(méi)有開(kāi)源)
中文全文搜索的關(guān)鍵是在分詞上.mysql本身不支持cjk的分詞(cjk:chinese,japanese,korean),
所以
!!!!****如何用php模擬分詞是mysql全文索引的關(guān)鍵****!!!!
中文分詞是語(yǔ)言分詞中最困難的.現(xiàn)在也沒(méi)有人能夠徹底完美的解決(雖然這些搜索引擎做的都還不錯(cuò).)
//fcicq:下面給大家看看這里php的分詞是怎么做的.
function &DV_ChineseWordSegment($str,$encodingName='gbk'){
static $objEnc = null;
if( $objEnc === null ){
if( !class_exists('DV_Encoding') ){
require_once ROOT_PATH.'inc/DV_Encoding.class.php';
}
$objEnc =& DV_Encoding::GetEncoding($encodingName);
}
$strLen = $objEnc->StrLength($str);
$returnVal = array();
if( $strLen < = 1 ){
return $str;
}
$arrStopWords =& DV_GetStopWordList();
//print_r($arrStopWords);
//過(guò)濾所有HTML標(biāo)簽
$str = preg_replace('#<[a-zA-Z]+?.*?>|#is', ”, $str);
//過(guò)濾所有stopword
$str = str_replace($arrStopWords['StrRepl'],' ‘,$str);
$str = preg_replace($arrStopWords['PregRepl'],' ‘,$str);
//echo “$str:{$str}
“;
$arr = explode(' ‘,$str);
//fcicq:好了,這下面的才是php分詞關(guān)鍵 *************
foreach( $arr as $tmpStr ){
if ( preg_match(”/^[x00-x7f]+$/i”,$tmpStr) === 1 )
{ //fcicq:全是E文,沒(méi)關(guān)系,mysql可以認(rèn)識(shí)的
$returnVal[] = ‘ ‘.$tmpStr;
} else{ //fcicq:中英混合…
preg_match_all(”/([a-zA-Z]+)/i”, $tmpStr, $matches);
if( !empty($matches) ){ //fcicq:英語(yǔ)部分
foreach( $matches[0] as $matche ){
$returnVal[] = $matche;
}
}
//過(guò)濾ASCII字符
$tmpStr = preg_replace(”/([x00-x7f]+)/i”, ”
, $tmpStr); //fcicq:你看,剩下的不就全是中文了?
$strLen = $objEnc->StrLength($tmpStr)-1;
for( $i = 0 ; $i < $strLen ; $i++ ){
$returnVal[] = $objEnc->SubString($tmpStr,$i,2)
; //fcicq:注意這里的substr,不是手冊(cè)上的.
//fcicq:你仔細(xì)看,所有的詞都是分成兩個(gè).
//比如”數(shù)據(jù)庫(kù)的應(yīng)用”,會(huì)被分成數(shù)據(jù) 據(jù)庫(kù) 庫(kù)的 的應(yīng) 應(yīng)用…
//全文搜索: 全文 文搜 搜索
//這分詞自然是不怎么樣的
//但是,搜索的時(shí)候同樣這么做.
//比如搜索數(shù)據(jù)庫(kù),就相當(dāng)于搜索了數(shù)據(jù) 據(jù)庫(kù).
//這是一種相當(dāng)傳統(tǒng)的全文搜索分詞方法.
}
}
}
return $returnVal;
}//end function DV_ChineseWordSegment
//fcicq:這就是傳說(shuō)中的substr.偶相信許多人寫(xiě)出來(lái)的php代碼都比這個(gè)好.
function &SubString(&$str,$start,$length=null){
if( !is_numeric($start) ){
return false;
}
$strLen = strlen($str);
if( $strLen < = 0 ){
return false;
}
if( $start < 0 || $length < 0 ){
$mbStrLen = $this->StrLength($str);
} else{
$mbStrLen = $strLen;
}
if( !is_numeric($length) ){
$length = $mbStrLen;
} elseif( $length < 0 ){
$length = $mbStrLen + $length - 1;
}
if( $start < 0 ){
$start = $mbStrLen + $start;
}
$returnVal = '';
$mbStart = 0;
$mbCount = 0;
for( $i = 0 ; $i < $strLen ; $i++ ){
if( $mbCount >= $length ){
break;
}
$currOrd = ord($str{$i});
if( $mbStart >= $start ){
$returnVal .= $str{$i};
if( $currOrd > 0×7f ){
$returnVal .= $str{$i+1}.$str{$i+2};
$i += 2;
}
$mbCount++;
} elseif( $currOrd > 0×7f ){
$i += 2;
}
$mbStart++;
}
return $returnVal;
}//end function SubString
//插入全文搜索分詞表.一共兩個(gè),一個(gè) topic_ft,一個(gè)bbs_ft
$arrTopicIndex =& DV_ChineseWordSegment($topic);
if( !empty($arrTopicIndex) && is_array($arrTopicIndex) ){
$topicindex = $db->escape_string(implode(' ‘,$arrTopicIndex));
if( $topicindex !== ” ){
$db->query(”UPD ATE {$dv}topic_ft SET topicindex='
{$topicindex}' WHERE topicid='{$RootID}'”);
} else{
$db->query(”DEL ETE FROM {$dv}topic_ft
WHERE topicid='{$RootID}'”);
}
}
}
這就是所謂的mysql全文搜索分詞,mysql不會(huì)分詞,而php會(huì)。就這么簡(jiǎn)單。
這雖然是一種比較過(guò)時(shí)的方法,但是非常實(shí)用。
MATCH (col1,col2,…) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION])
比如:
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');
MATCH()函數(shù)對(duì)于一個(gè)字符串執(zhí)行資料庫(kù)內(nèi)的自然語(yǔ)言搜索。一個(gè)資料庫(kù)就是1套1個(gè)或2個(gè)包含在FULLTEXT內(nèi)的列。搜索字符串作為對(duì) AGAINST()的參數(shù)而被給定。對(duì)于表中的每一行, MATCH() 返回一個(gè)相關(guān)值,即, 搜索字符串和 MATCH()表中指定列中該行文字之間的一個(gè)相似性度量。
下面的例子則更加復(fù)雜。詢(xún)問(wèn)返回相關(guān)值,同時(shí)對(duì)行按照相關(guān)性漸弱的順序進(jìn)行排序。為實(shí)現(xiàn)這個(gè)結(jié)果,你應(yīng)該兩次指定 MATCH(): 一次在 SELECT 列表中而另一次在 WHERE子句中。這不會(huì)引起額外的內(nèi)務(wù)操作,原因是MySQL 優(yōu)化程序注意到兩個(gè)MATCH()調(diào)用是相同的,從而只會(huì)激活一次全文搜索代碼。
復(fù)制代碼 代碼如下:
mysql> SELECT id, body, MATCH
(title,body) AGAINST
-> ('Security implications of
running MySQL as root') AS score
-> FROM articles WHERE MATCH
(title,body) AGAINST
-> ('Security implications of
running MySQL as root');
所以,到這里你應(yīng)該會(huì)mysql 英文全文搜索了.
請(qǐng)注意一個(gè)問(wèn)題.
一些詞在全文搜索中會(huì)被忽略:
* 任何過(guò)于短的詞都會(huì)被忽略。 全文搜索所能找到的詞的默認(rèn)最小長(zhǎng)度為 4個(gè)字符。
* 停止字中的詞會(huì)被忽略。
mysql還自帶查詢(xún)擴(kuò)展功能.這里不做過(guò)多討論.
下面進(jìn)行php中文全文搜索的分析
曾經(jīng)有一個(gè)版本的mysql支持中文全文搜索(海量 mysql chinese+,說(shuō)是GPL但是最終沒(méi)有開(kāi)源)
中文全文搜索的關(guān)鍵是在分詞上.mysql本身不支持cjk的分詞(cjk:chinese,japanese,korean),
所以
!!!!****如何用php模擬分詞是mysql全文索引的關(guān)鍵****!!!!
中文分詞是語(yǔ)言分詞中最困難的.現(xiàn)在也沒(méi)有人能夠徹底完美的解決(雖然這些搜索引擎做的都還不錯(cuò).)
復(fù)制代碼 代碼如下:
//fcicq:下面給大家看看這里php的分詞是怎么做的.
function &DV_ChineseWordSegment($str,$encodingName='gbk'){
static $objEnc = null;
if( $objEnc === null ){
if( !class_exists('DV_Encoding') ){
require_once ROOT_PATH.'inc/DV_Encoding.class.php';
}
$objEnc =& DV_Encoding::GetEncoding($encodingName);
}
$strLen = $objEnc->StrLength($str);
$returnVal = array();
if( $strLen < = 1 ){
return $str;
}
$arrStopWords =& DV_GetStopWordList();
//print_r($arrStopWords);
//過(guò)濾所有HTML標(biāo)簽
$str = preg_replace('#<[a-zA-Z]+?.*?>|#is', ”, $str);
//過(guò)濾所有stopword
$str = str_replace($arrStopWords['StrRepl'],' ‘,$str);
$str = preg_replace($arrStopWords['PregRepl'],' ‘,$str);
//echo “$str:{$str}
“;
$arr = explode(' ‘,$str);
//fcicq:好了,這下面的才是php分詞關(guān)鍵 *************
foreach( $arr as $tmpStr ){
if ( preg_match(”/^[x00-x7f]+$/i”,$tmpStr) === 1 )
{ //fcicq:全是E文,沒(méi)關(guān)系,mysql可以認(rèn)識(shí)的
$returnVal[] = ‘ ‘.$tmpStr;
} else{ //fcicq:中英混合…
preg_match_all(”/([a-zA-Z]+)/i”, $tmpStr, $matches);
if( !empty($matches) ){ //fcicq:英語(yǔ)部分
foreach( $matches[0] as $matche ){
$returnVal[] = $matche;
}
}
//過(guò)濾ASCII字符
$tmpStr = preg_replace(”/([x00-x7f]+)/i”, ”
, $tmpStr); //fcicq:你看,剩下的不就全是中文了?
$strLen = $objEnc->StrLength($tmpStr)-1;
for( $i = 0 ; $i < $strLen ; $i++ ){
$returnVal[] = $objEnc->SubString($tmpStr,$i,2)
; //fcicq:注意這里的substr,不是手冊(cè)上的.
//fcicq:你仔細(xì)看,所有的詞都是分成兩個(gè).
//比如”數(shù)據(jù)庫(kù)的應(yīng)用”,會(huì)被分成數(shù)據(jù) 據(jù)庫(kù) 庫(kù)的 的應(yīng) 應(yīng)用…
//全文搜索: 全文 文搜 搜索
//這分詞自然是不怎么樣的
//但是,搜索的時(shí)候同樣這么做.
//比如搜索數(shù)據(jù)庫(kù),就相當(dāng)于搜索了數(shù)據(jù) 據(jù)庫(kù).
//這是一種相當(dāng)傳統(tǒng)的全文搜索分詞方法.
}
}
}
return $returnVal;
}//end function DV_ChineseWordSegment
//fcicq:這就是傳說(shuō)中的substr.偶相信許多人寫(xiě)出來(lái)的php代碼都比這個(gè)好.
function &SubString(&$str,$start,$length=null){
if( !is_numeric($start) ){
return false;
}
$strLen = strlen($str);
if( $strLen < = 0 ){
return false;
}
if( $start < 0 || $length < 0 ){
$mbStrLen = $this->StrLength($str);
} else{
$mbStrLen = $strLen;
}
if( !is_numeric($length) ){
$length = $mbStrLen;
} elseif( $length < 0 ){
$length = $mbStrLen + $length - 1;
}
if( $start < 0 ){
$start = $mbStrLen + $start;
}
$returnVal = '';
$mbStart = 0;
$mbCount = 0;
for( $i = 0 ; $i < $strLen ; $i++ ){
if( $mbCount >= $length ){
break;
}
$currOrd = ord($str{$i});
if( $mbStart >= $start ){
$returnVal .= $str{$i};
if( $currOrd > 0×7f ){
$returnVal .= $str{$i+1}.$str{$i+2};
$i += 2;
}
$mbCount++;
} elseif( $currOrd > 0×7f ){
$i += 2;
}
$mbStart++;
}
return $returnVal;
}//end function SubString
//插入全文搜索分詞表.一共兩個(gè),一個(gè) topic_ft,一個(gè)bbs_ft
$arrTopicIndex =& DV_ChineseWordSegment($topic);
if( !empty($arrTopicIndex) && is_array($arrTopicIndex) ){
$topicindex = $db->escape_string(implode(' ‘,$arrTopicIndex));
if( $topicindex !== ” ){
$db->query(”UPD ATE {$dv}topic_ft SET topicindex='
{$topicindex}' WHERE topicid='{$RootID}'”);
} else{
$db->query(”DEL ETE FROM {$dv}topic_ft
WHERE topicid='{$RootID}'”);
}
}
}
這就是所謂的mysql全文搜索分詞,mysql不會(huì)分詞,而php會(huì)。就這么簡(jiǎn)單。
這雖然是一種比較過(guò)時(shí)的方法,但是非常實(shí)用。
相關(guān)文章
淺談Mysql連接數(shù)據(jù)庫(kù)時(shí)host和user的匹配規(guī)則
這篇文章主要介紹了淺談Mysql連接數(shù)據(jù)庫(kù)時(shí)host和user的匹配規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01MYSQL必知必會(huì)讀書(shū)筆記第二章之版本更改
本文是小編日常收集整理些有關(guān)mysql必知必會(huì)筆記整理第二章,小編感覺(jué)非常實(shí)用,特此分享到腳本之家平臺(tái),供大家參考2016-05-05MySQL數(shù)據(jù)庫(kù)性能優(yōu)化介紹
大家好,本篇文章主要講的是MySQL數(shù)據(jù)庫(kù)性能優(yōu)化介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12MySQL慢查詢(xún)?nèi)罩局械腖ock_time由來(lái)解析
這篇文章主要為大家介紹了慢查詢(xún)?nèi)罩局蠰ock_time的由來(lái)解析,以及Lock_time?包含哪些鎖等待時(shí)間、以及是怎么計(jì)算得到的,有需要的朋友可以借鑒參考下,希望能夠有所幫助2023-06-06MySql存儲(chǔ)過(guò)程和游標(biāo)的使用實(shí)例
我們?cè)趯?shí)際的開(kāi)發(fā)中會(huì)遇到一些統(tǒng)計(jì)的業(yè)務(wù)功能,如果我實(shí)時(shí)的去查詢(xún)的話有時(shí)候會(huì)很慢,此時(shí)我們可以寫(xiě)一個(gè)存儲(chǔ)過(guò)程來(lái)實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于MySql存儲(chǔ)過(guò)程和游標(biāo)使用的相關(guān)資料,需要的朋友可以參考下2022-04-04ubuntu mysql 5.6版本的刪除/安裝/編碼配置文件配置
這篇文章主要介紹了ubuntu mysql 5.6版本的刪除,安裝,編碼配置文件配置,需要的朋友可以參考下2017-06-06