首先 你需要維護一個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內解決問題,這樣基本是在使用者的耐心裡完成的