lucene 的php tag 词库搜索法的变通

首先 你需要维护一个tag库,这个库不能太大,我测试的是 1w条数据,如果是一个垂直网站应该差不多能够用了.

tag 表应该有如下字段
tag_id                    标签id
tag_word                   标签内容
tag_lent                  标签长度
tag_content_id            所有含有该标签的id集合

使用的文件生成
取得tag标签,作为词库文件生成  暂时叫 ciku.tmp 吧

然后取得 tag_content_id 连上文章表,取得id跟文章标题

然后保存成文件     暂时叫 cache.temp

这2个文件什么时候都可以建立.并不影响用户使用,因为这些全是准备工作,并没有真正的给用户使用,也就是说,用户去搜索的时候
并不是时时的 数据,而且搜索我们存储的缓存文件.

那好我们现在开始 用户的前台使用

现在用户输入了 一个 词 比较叫 我爱搜索,但是我不会

好我们开始匹配,
我们加载词库
然后 进行循环比对 我们现在取得 现在得到了一个 次,是我们库里的tag 就是搜索
而搜索有1w条数据.
我们现在加载 tag 搜索 的 文件 首先,文件里存储的数据是有格式的,我的格式是 文件id||栏目id||标题

现在我们开始分析 结果集合里的数据
然后根据固定的url格式生成url,给用户展现.ok搜索完成了.这也就是个 搜索的 索引

现在说另外一个问题
tag_lent 这个我们并没用用到,是干什么用的呢? 这个减少我们的词库用的,比如用户录入的 数据 是4个长度的,那么我们从数据库中
就把长度长过4的tag过滤掉,好处就是减少词的量,加快搜索速度.

现在另外一个问题就分页
我们把所有的数据都放带一个文件里了,我们都加载近来,然后我们根据分页来分析数组显示就行了.

现在再说一个问题,就是复合搜索了

那么好,我们现在从用户输入的数据里匹配出来了我们词库中的2个tag,那么我们就加载2个文件,这个时候有个问题,我要跟大家说下,如果是2个文件的话,大概数据就不好整理了
我们需要把2个文件里的数据整理到一个数组里,然后分析就可以了,或者我们采用php的数组原理,我们不使用 file()这个函数,而是直接include近来文件,但是我文件的格式
要有所约定了比如 $search[] 这样的形式,那么我们就可以顺利的分页了.关于其他的方式还是大家自己努力想想吧

或者是多个数组,有一个命名规则

利用 array_diff 取得差集
利用array_intersect 交集
利用 array_unshift 在 差集 头插入 交集

执行不定参数的php函数
$a = array('a','b','c');
$b = array('b','c','d');
eval("/$t=array_diff(/$a,/$b);");
print_r($t);

$a0 = array('a','b','c');
$a1 = array('b','c','d');
for($i=0;$i<2;$i++)
{
 $str[] = "/$a{$i}";
}
eval("/$t=array_diff(".implode(',',$str).");");
print_r($t);

关于这个搜索解决方案的缺点
由于,是预先生成的,所有会有延时
缺点2,由于是都要加载到内存里操作,有可能会出现数组过大,超过php最大内存使用的情况,请大家酌情使用.
缺点3,没办法增量建立索引
现在给大家一个我的测试用例
[code]
<?php
include_once("FileIO.class.php");
class execTime{
 var $startTime = "";
 var $endTime = "";
 function execTime()
 {
  $this->startTime = $this->gettime();
 }
 function gettime()
 {
  list($usec,$sec)=explode(" ",microtime());
  return (float)$usec + (float)$sec;
 }
 function showTime()
 {
  $this->endTime = $this->gettime();
  echo 'page exec time is :'.($this->endTime-$this->startTime).' s';
 }
}
$f = "|!|";
for($i=0;$i<10000;$i++)
{
 $search[] = "0001{$f}0123{$f}我爱你{$i}";
}
$fileName = "cache.temp";
FileIO::writeFile($fileName,implode("/n",$search));

$str = "我来了我来了我来了我来勒令";

$exec = new execTime();

$c=count($search);
for($i=0;$i<$c;$i++)
{
 strrpos($search[$i],$str);
}
$content = file($fileName);
$c=count($content);
for($i=0;$i<$c;$i++)
{
 $t=$content[$i];
 //print_r(explode($f,$t));exit();
 list($aid,$cid,$title) = explode($f,$t);
 $a = "{$aid}-----{$cid}-------{$title}";
}

$exec->showTime();

?>
[/code]

使用的时间是 page exec time is :1.80978298187 s

我感觉 如果顺利的话,大概能在 2s内解决问题,这样基本是在用户的耐心里完成的


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>