首先 你需要维护一个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内解决问题,这样基本是在用户的耐心里完成的