首頁 > 後端開發 > php教程 > PHP+MYSQL實作全文檢索及全文檢索工具

PHP+MYSQL實作全文檢索及全文檢索工具

巴扎黑
發布: 2023-03-01 09:10:01
原創
13426 人瀏覽過

如何使用PHP實現全文檢索功能?
很多人可能馬上可以想出幾個方案,例如:文件檢索法、採用SQL的like語句等方法,但這些方法效率都相當的低。
這裡介紹一種比較有效率的PHP全文檢索實作方法,這就是採用MYSQL的FULLTEXT欄位類型。但MYSQL的FULLTEXT欄位對中文的支援不是很好,本文也一併介紹如何透過PHP+MYSQL實作中文全文檢索功能。
首先需要用到一個PHP中文分詞擴充模組??SCWS,關於這個模組的安裝和使用大家可以到www.ftphp.com/scws去尋找相關內容(如有問題請留言)。
接著再看看mysql的fulltext欄位類型的相關資訊:
MySQL3.23.23之後的版本開始支援全文索引和搜尋。全文索引在 MySQL 中是一個 FULLTEXT 類型索引。
FULLTEXT 索引用於 MyISAM 表,可以在 CREATE TABLE 時或之後使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、VARCHAR 或 TEXT 欄位上建立。對於大的資料庫,將資料裝載到一個沒有 FULLTEXT 索引的表中,然後再使用 ALTER TABLE (或 CREATE INDEX) 建立索引,這將是非常快的。將資料裝載到一個已經有 FULLTEXT 索引的表中,將會是非常慢的。

MYSQL全文搜尋透過 MATCH() 函數完成。
下面舉一簡單例子:
1、新建資料表:

CREATE TABLE fulltext_sample(copy TEXT,FULLTEXT(copy)) TYPE=MyISAM;
登入後複製

這裡的copy就是一個fulltext類型的字段,如果建表的時候沒有添加全文檢索字段,也可以透過alert來添加,如:

ALTER TABLE fulltext_sample ADD FULLTEXT(copy)
登入後複製

2、插入資料:

INSERT INTO fulltext_sample VALUES
('It appears good from here'),
('The here and the past'),
('Why are we hear'),
('An all-out alert'),
('All you need is love'),
('A good alert');
登入後複製

3、資料擷取:

SELECT * FROM fulltext_sample WHERE MATCH(copy) AGAINST('love');
登入後複製

上面就是mysql的全文檢索功能,注意:在全文索引上搜尋是不區分大小寫的。

下面再看如何實現中文全文檢索。
fulltext字段是以詞語為單位,詞語之間需要用空格隔開,而漢語的句子中各個詞語之間並不會用空格隔開,因此我們需要對中文進行分詞,這也就​​是為什麼上面需要強詞用到中文分詞擴充模組。
但是儘管對中文進行分詞,MYSQL還是不能透過MATCH來實現中文的全文檢索,這需要透過一定的方法來進行轉換,一個比較簡單實用的方法是採用下面這個函數(當然還有更好的),它將中文進行了urlencode轉換。

function q_encode($str)
{
$data = array_filter(explode(" ",$str));
$data = array_flip(array_flip($data));
foreach ($data as $ss) {
  if (strlen($ss)>1 ) 
   $data_code .= str_replace("%","",urlencode($ss)) . " ";
}
$data_code = trim($data_code);
return $data_code;
}
登入後複製

將轉換過後的內容儲存至事先定義好的fulltext欄位。同樣,在查詢的時候也需要將查詢的關鍵字進行同樣方法的轉換。

PHP+Mysql實現UTF8全文搜尋的方法

本文講解一下如何在海量的資料中能夠快速的進行全文檢索呢? MySQL提供了一個全文索引功能,也就是把欄位設定上FULLTEXT索引屬性,然後透過SELECT的MATCH AGAINST語句來找出。

我們開發的一個純英文網站TouchUs - The Global Yellow Pages & Business Directory(www.touchus.org)就是利用MySQL的這項功能,實現了對十多萬個資料的平均全文檢索時間小於0.5秒。但在開發TouchUs的中文網站??城市黃頁網時(www.city39.cn),碰到了新的問題。原來英文排版時詞和詞之間是透過空格區分的,FULLText可以完全支持,但是對中文或者是東亞文字就沒有這麼簡單了,因為中文的詞和詞之間並沒有明顯的分隔,所以MySQL不支援中文字元的全文檢索。

如何讓MySQL也能支援中文的全文檢索呢?偶然間產生了一個思路,那就是能不能在中文分詞後,透過對中文進行編碼轉化成英文字符,這樣就在中英文間建立一個特定的聯繫,然後再進行全文檢索,這樣不就實現了中文的全文索引了嗎?經過試驗,答案是肯定的。以下是在城市黃頁網中實現的具體過程:

1. 建立一個單獨的索引表,例如對應members表,我們建立一個members_index表。

用戶信息表(members)                    用戶信息全文索引表(members_index)

User_id                                              user_id

User_name                                       index_intro

User_introduction                                   

在members_index表的index_intro中加入fulltext索引。

2. 對使用者資訊表(members)的User_introduction欄位內容進行中文分詞處理

中文分词的处理过程,可以参考简易中文分词系统http://www.ftphp.com/scws/,在城市黄页网中,我们采用了scws的PHP扩展模块方式来实现中文分词。scws的php扩展模块安装非常简单,只需简单编译配置后即可使用。在具体的php代码中,我们写了如下的函数来实现分词后将分词结果用空格进行连接。

//中文分词函数
function str_fc($str) {
$so = scws_new();
$so->set_charset('utf8');
// 这里没有调用 set_dict 和 set_rule 系统会自动试调用 ini 中指定路径下的词典和规则文件
$so->send_text($str);
while ($tmp = $so->get_result())
{
foreach (  $tmp as $ss ){
$s = trim($ss[word]);
if ( $s )
$mystr .= trim($ss[word]) . " ";
//echo urlencode(trim($ss[word])) . " ";
}
}
return $mystr;
}
登入後複製

该函数返回就是用空格连接的分词结果。

3. 对分词结果进行编码,可以采用多种编码方式,比如base64编码、urlencode编码、汉字转拼音等,对gb2312甚至可以采用区位码编码方式。考虑到存储空间以及便利性,我们采用了PHP的urlencode编码方式。需要注意的是,在编码前,我们可以去掉重复的分词来节约存储空间,编码后要去掉编码结果中的%符号,因为urlencode采用RFC 1738???行编码,会产生很多%,而%在MySQL是通配符。下面是编码过程用到的PHP代码

$data = str_fc($data);  //中文分词
$data = array_filter(explode(" ",$data)); //删除数组空项
$data = array_flip(array_flip($data));  //删除重复项
//对分词结果进行urlcode编码
foreach (  $data as $ss ) {
if (strlen($ss)>1 )
$data_code .= str_replace("%","",urlencode($ss)) . " ";
}
登入後複製

这里的$data_code就是编码后的结果。把编码结果根据user_id存入用户信息全文索

引表(members_index)

4. 在进行搜索处理时,首先对用户输入的关键字进行同样的分词编码处理,然后通过MySQL的SELECT的MATCH  AGAINST语句进行全文快速检索,根据检索结的user_id即可调用用户信息表(members)中的原始数据进行显示,而没有必要进行一次解码重组。

以上MySQL UTF8中文全文检索方法.

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板