关于虚拟主机上的简单全文索引解决方案

很久之前就想写一篇关于全文索引的文章,但是最近忙着准备毕业设计和考试一直没有写。前段时间log,升级了一下站内搜索的方案。原先设计的时候是用%like%进行全文搜索的,自己都不忍直视这样干瘪的搜索。想让mysql做全文索引搜索,什么都不说,先得把一大串的汉字给分成单词吧,英文天生支持全文索引,但是汉字都连在一起的,得自己动手分。于是在网上找了一些关于mysql全文索引的文章。百度出来的全文搜索引擎相关的文章,基本都一样,同一篇文章出现在了大多数的技术论坛。

1sphinx的seekcore

不必说,mysql全文搜索的不二方案,为mysql所问索引而生的第三方软件。coreseeksphinx的衍生版本,为适应中国市场而生做了很多本土化的优化。之前在公司实习的时候有接触过sphinx,但是没有深入研究。拿到sphinx高兴啊,立即装上百度找一些配置文章。装好之后才想起来我用的是虚拟空间,虚拟空间装什么sphinx啊。

2、海曼大神pscws分词神器

首先我想说网上很多人都说highman的分词神器,但是不知道多少人用过了,highman个人现在应该是把大部分时间放在迅搜上边,关于分词的pscws已经很久没更新了。迅搜和seekcore一样都是建立在服务器端的,这种解决方案对只能虚拟空间的屌丝来说几乎不太可能实现。首先我想说highmanpswcs在高版本php下支持是不怎么好的,之前用的是5.01的没有报错,后来换了5.4+php版本结果上来直接一脸的错。能在虚拟机上运行的分词php文件有两个一个pswcs23还有一个pswcs4,官方说pswcs4速度较慢不推荐使用,剩下的只有23两个版本了。看了一下速度还不错。注意pswcs2pswcs3只支持gbk形式文件。

当初自己没看清楚文档,吃不少苦,整整调试了三天全是乱码,害得我一个项目全跟着乱码巴拉巴拉看源代码,看得稀里糊涂没发现什么错了,最后在一字一句的去读了文档才发现只支持gbk编码。还好我是随时备份的。我用的是nodepad++默认是utf-8编码,所以是没法分割,只有乱码。而且数据库也是utf-8的编码,后来一运行我整个项目全乱码,什么验证码无法显示啊,乱七八槽。所以我再次提醒就算你全都用gbk形式来编码,做用之前别直接放到项目里边去测试。海曼的pswcs我研究了好几天,也得到了解决方案。解决方案请耐心看完下边关于另个方法的介绍。待会一起提到。

3、下面介绍关于二元法全文索引解决方案。

研究海曼哥哥的东西最后无功而返,倍受打击本来打算放弃了的。后来去研究了discuzecshop的站内搜索引擎,没有惊喜,无例外的用like只是在提交的搜索做了简单的处理全文索引用不上。百无聊赖躺在床上的时候用百度百科看了一下全文索引的定义,看到二分法做分词的方法,想想这倒是解决方案。然后花了一天去百度啊,找啊,终于找到了一个分词算法,因为不知道到底谁是原创,就不引用作者了。同样的问题,乱码,又不支持utf8

后来转念一想php不是可以转码吗?既然php可以转码,那么编码的问题就不存在了。

Ok到这里基本上问题都可以解决了。虽然可以转码,但是因为弄错了gbkutf-8ASCii码,害得我折腾了两天。把源代码看了无数遍。下面是我做的修改,我想再啰嗦一遍,网上有的哪个二元分词法是不正确的,只能分gbk,而且会把字符里的英文全过滤掉,我在这里做了点修正。

先说一下二元法分词怎么做:

(1)、如果要对一张article的表建立全文索引,那么得借助另一张变index来存放分词后的文本字符。两张表外键相关(分词后再逆回去是不现实的,而且建立全文索引之后写操作是相当吃力的)。

(2)、msyql支持中文分词,最起码在my.ini里边加上这句ft_min_word_len = 1

这里有一边官文全文索引很好的文章可以参考一下,接下来怎么做我就不多说了

http://www.cnblogs.com/macula7/archive/2011/05/18/2050525.html

/**
 * 二元发分割中文字符,可以对不同编码的中文进行分词
 * @param string $name 转入字符串
 * @return string
 */
 
function spl_zhstr($strings) {
	$str=$strings;
	$encode = mb_detect_encoding($str, array("ASCII","UTF-8","GB2312","GBK","BIG5")); 
	$str=iconv($encode,"GBK",$str);//更改编码,转为gbk,以一个汉字两个字节分词
	preg_match_all('/[0-9a-z]+?/U',$str,$enlg);
	$enword=implode(' ',$enlg[0]);//获得英文单词
	$charset= "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
	$str=preg_replace($charset,"\\0".chr(0x00),$str);//为了分词准确在每个单词后加'.'
	$search = array(",", "/", "\\", ".", ";", ":", "\"", "!", "~", "`", "^", "(", ")", "?", "-", "\t", "\n", "'", "<", ">", "\r", "\r\n", "$", "&", "%", "#", "@", "+", "=", "{", "}", "[", "]", ":", ")", "(", ".", "。", ",", "!", ";", "“", "”", "‘", "’", "〔", "〕", "、", "—", " ", "《", "》", "-", "…", "【", "】",);
	$str = str_replace($search,' ',$str);
    preg_match_all("/[\x80-\xff].?/",$str,$ar);
	$ar=$ar[0];
    for ($i=0;$i<count($ar);$i++) 
		if($ar[$i]!=chr(0x00)) {
		$ar_new[]=$ar[$i];//将单词压入数组
	}
    $ar=$ar_new;
	$oldsw=0;
    for ($ar_str='',$i=0;$i<count($ar);$i++) {
		$sw=strlen($ar[$i]);
    if ($i>0 and $sw!=$oldsw) 
		$ar_str.=' ';
      if ($sw==1)
		$ar_str.=$ar[$i];
	
      else
		if (@strlen($ar[$i+1])===2)
			$ar_str.=$ar[$i].$ar[$i+1].' ';
		elseif ($oldsw==1 or $oldsw==0) 
			$ar_str.=$ar[$i];
      $oldsw=$sw;
    }
    $ar_str=trim(preg_replace("#\s{1,}#i"," ",$ar_str));
	$word=$ar_str;//.' '.$enword;
	$encode = mb_detect_encoding($word, array("ASCII","UTF-8","GB2312","GBK","BIG5")); 
	$word=iconv($encode,"utf-8",$word);//编码转回utf-8
	return $word;
}


关于pscws的的解决方案:

既然编码不是问题,那么就很容易了。如果appserv集成环境的我建议你该到wamp下来,因为appserv2.59太老了,2.6版本有太新了,php6都没正式发行就参合进去了。相对而言wamp的版本会多一点。但是我用的版本下一屏幕都是这个错Strict standards: Redefining already defined constructor for class PSCWS2,我想是highman大神太久没有更新了,文坛都是2008年的,我才上高中。我现在没有时间去研究为什么他会报错了,指导老师天天催着做设计(我的专业和计算机不搭嘎)。但是把php.inidisplay erros屏蔽掉时候还是能看到结果的。

下面是一个测试demo,我测过可以分词,不管是gbk/gb2312 还是utf-8,都可以成功分词。关于pscws请到官方自行下载http://www.xunsearch.com/scws/

 

require 'pscws2.class.php';

$str="你好吗天气好吗";

$encode = mb_detect_encoding($str, array("ASCII","UTF-8","GB2312","GBK","BIG5")); //获得编码

echo $encode;

$str=iconv($encode,"GBK",$str);//转码

$pscws = new PSCWS2('./dict/dict.xdb');//实例化对象,参数为路径,部分省略详见官网

$res = $pscws->segment($str);//返回的是数组哦

$res=implode(" ",$res);

$encode = mb_detect_encoding($res, array("ASCII","UTF-8","GB2312","GBK","BIG5")); 

$res=iconv($encode,"UTF-8",$res);

echo $encode;
print_r($res);

 

这是我的个人网站:http://www.hunhun234.com

最后唠叨一点。我也在学习web开发中,如果存在出错,请给我反馈:craber234@sina.cn

昨天才放到虚拟主机上,本地实现了全文索引,很遗憾虚拟主机不给改mysql参数故无法进行全文索引搜索,所有和全文索引相关的功能全废了,后来不情愿的改回了like模式。只是简单的测试,还有很多BUG。因为要毕业了,要做毕业设计,最近被老师下了最后通牒,所以没时间玩web了,不然就毕不了业了。一直在firefox和google chrome下开发所以不太顾及ie的兼容性,本人不太喜欢ie。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值