前日在用xiuno bbs 搜索插件时,发现全文索引很多都没有结果。于是看了查插件的代码,原来中文和一些短词都没有处理,
于是自己动手把我以前用的一个全文检索的处理方法拿来替换了一下,发现效果很好。这里分享一下。
plugin/xn_search/model/search_func.php第30行开始的整个函数,直接替换为:
function search_cn_encode($s) {
// 对 UTF-8 字符的汉字进行编码,转化为 mysql 可以索引的 word
$r = '';
// 替换特殊字符
$special_arr = array(
'0' , '1' , '2' , '3' , '4' ,
'5' , '6' , '7' , '8' , '9' ,
'A' , 'B' , 'C' , 'D' , 'E' ,
'F' , 'G' , 'H' , 'I' , 'J' ,
'K' , 'L' , 'M' , 'N' , 'O' ,
'P' , 'Q' , 'R' , 'S' , 'T' ,
'U' , 'V' , 'W' , 'X' , 'Y' ,
'Z' , 'a' , 'b' , 'c' , 'd' ,
'e' , 'f' , 'g' , 'h' , 'i' ,
'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' ,
't' , 'u' , 'v' , 'w' , 'x' ,
'y' , 'z' , '-' , ' ' , ':' ,
'.' , ',' , '/' , '%' , '#' ,
'!' , '@' , '&' , '(' , ')' ,
'<' , '>' , '"' , ''' , '?' ,
'[' , ']' , '{' , '}' , '\' ,
'|' , '+' , '=' , '_' , '^' ,
'¥' , ' ̄' , '`', '《', '》',
'【', '】', '〖', '〗', '『', '』',
'我', '你', '不', '是', '的', '了',
'nbsp', ' ',
);
$s = str_replace($special_arr, '', $s);
$r = '';
$s = trim($s);
$slen = strlen($s);
if($slen < 2)
{
return $s;
}
for($i=0; $i<$slen; $i++)
{
$o = ord($s[$i]);
if($o>0x80)
{
$c = $s[$i].$str[$i+1].$s[$i+2];
$i+=2;
$r .= urlencode($c)." ";
}
elseif( preg_match("/[a-z0-9]/i", $s[$i]) )
{
if( preg_match("/[a-z0-9]/i", $s[$i+1]) ) $r .= $s[$i];
else $r .= $s[$i].' ';
}
else
{
if($s[$i]!=' ') $r .= $s[$i].' ';
}
}
$r_a=explode(' ',$r);
$r = '';
foreach($r_a as $a)
{
$l=strlen($a);
if($l<4)
{
for($n=0;$n<4-$l;$n++)
{
$a.='A';
}
}
$r .= $a.' ';
}
return str_replace('%','',$r);
}
因为mysql的全文索引默认是对短词过滤掉的,也就是不索引也搜索不到,InnoDB全文搜索中默认是3个字符,MyISAM默认4个字符,虽然可通过改变配置参数来让他不过滤,(InnoDB改innodb_ft_min_token_size=1,MyISAM改ft_min_word_len=1,直接添加到mysql配置文件里面,表示对1个或1个以上的字符进行索引);另外诸如“the”、“or”、“and”等常用单词,这些词通常被认为没有什么语义价值,也一样被过滤。
但是很多站长可能没条件或者不会改,所以,我这里直接把不到4个字符的补到4个(少几个就加几个A在后面),并且对汉字进行urlencode转码,这样就不会因为mysql对汉字索引支持不好影响搜索结果。
改完以后基本都能搜索到了,当然,英文单词没有把字母分开也会对搜索结果有些影响,比如urlencode,如只搜索urlen可能会搜索不到,除非所有的字母全部补全到4个字符单独索引,但是好像不是很有必要。
不然就只能用like做低效率搜索了……
最后于 2018-2-13
被三郎编辑
,原因: 修正