在php+mysql
構架的**中,大資料量的全文檢索一般都會用到
mysql
的fulltext
全文索引,通過
select...match...against
語句來進行查詢。
迄今為止,mysql
對中文全文索引無法正確支援,
mysql
是不會識別中文詞語的。參照
mysql
識別英文單詞機制,要建立中文全文索引,暫時的解決方案只有手動將中文分詞(以空格的形式將中文詞語分開),來將中文轉換成
mysql
認識的語言。
如今網上對於中文分詞的解決方案有很多,有基於mysql
外掛程式的,有談論演算法思想的。基於外掛程式(如
海量科技的
mysql--linuxx86-chinese+
,hightman
開發的mysql
--ft-hightman
)的方式主要通過對mysql
資料庫安裝乙個別人提供好的外掛程式,在建
fulltext
索引的字段時後面加上
with parser
×××(大多都是這樣)的形式。而基於演算法思想的則大部分工作都要自己完成,但他們的大體思想都差不多:
1. 對插入的要建全文索引的中文資料進行分詞;
2. 將原始資料和分詞後的資料都存入資料庫中,並以某種方式建立聯絡;
3. 在儲存分詞資料的字段上建立fulltext
索引;4.
查詢時以select...match...against
的方式在分詞欄位上搜尋,將搜到的行通過前面建立的聯絡找到原始資料行並返回。
而我們在討論解決方案時,考慮到使用開源外掛程式的話可控性比價差,而且外掛程式會對mysql
做一些改變,我們決定將分詞儲存的工作自己寫**完成,這樣雖然工作量加大,但以後的維護成本卻降低了很多。下面我們來看下大體實現。
一、首先,先建立資料庫
要注意的是只有myisam
表型別才能支援
fulltext
,myisam
與innodb
各有優劣,我們決定將原始資料與索引分表儲存,原始資料存入
innodb
表,同時建立
myisam
表存入作為檢索的字段和用於關聯的字段
id。這裡我建立了兩張表
questions
和questions_idx
:其中,title
和detail
是要建立全文索引的字段,而
id則是建立兩張表的聯絡。值得注意的是,
myisam
是不支援事務和外來鍵的,因此對於兩張表資料的同步還要靠額外**邏輯來實現。
還有就是索引欄位有可能需要比原始資料更大的空間,這裡我分配了2
倍(這個是我隨意想的,有可能需要更多)。
二、接著,討論中文分詞
網上流傳的分詞方法有很多,主要有基於演算法的(比如二元分詞演算法,
位元組交叉切分演算法
)和基於詞庫的。基於演算法是不必要維護詞庫的,而詞庫法則必須維護詞庫,有可能跟不上詞彙的發展。
實際上現在很多著名的搜尋引擎都使用了多種分詞的辦法,比如「
正向最大匹配」+
「逆向最大匹配
」,基於統計學的新詞識別,自動維護詞庫等技術
。我們採用的是基於詞庫的,並且使用了
hightman的
scws
的php
擴充套件模組方式。參考
。這個開源分詞系統這裡不多說,總之利用的是詞庫來分詞,而且最新版的是支援自定義詞庫的,這對於我們的內部**來說,詞庫的維護問題變得簡單了,因為新增詞彙不會像外部**那麼大,也不需要維護太多。
下面定義了類
cws,方法
get_idx
將輸入中文資料,輸出分詞並編碼後的資料:
class cws對於scws}$so->close();
//--------編碼-----------
$data = array_filter(explode(" ",$output)); //刪除陣列空項
$data = array_flip(array_flip($data)); //刪除重複項
//對分詞結果進行urlcode編碼
foreach ($data as $ss)
}return $data_code;
}}
的那段**請參照
scws
使用手冊。
而對於為什麼要進行編碼,網上大都解釋是:
mysql系統自變數規定了全文檢索被編入索引單詞的最小長度和最大長度
(ft_min_word_len
和ft_max_word_len)
,預設的最小值為
4個字元
,預設的最大值取決於使用的 mysql
版本。
參考為了不改變這個預設值同時也是兼考慮這個值對於英文的意義,則需要通過編碼將中文詞變長。
而對於編碼,網上流傳的方式也有很多,
比如base64
編碼、urlencode
編碼等,甚至還有
漢字轉拼音
。這裡我嘗試了urlencode
編碼,需要注意的是
urlencode
會產生很多』%
』,這在mysql
中是萬用字元,要去掉。
三、插入資料
插入資料的時候我們就要呼叫以上的函式了:
public function add($title, $detail, $askerid)四、搜尋資料
還是檢索不到:
public function search($word, $limit)
MYSQL 百萬條記錄全文檢索中文解決方案
mysql最適合用於小型運用的開發。遇到了單錶上百萬記錄。用select from where like 去查詢,結果效率低到難以忍受。五十萬條記錄竟然用了三十秒才出結果!這對於任何運用都是沒辦法忍受的。對應大資料量查詢的時候,很多資料庫是支援全文檢索的。首先我的表預設是 innodb,這種表的型別...
關於全文檢索的解決方案實現
應用場景 需要在大量資料中完成快速檢索 批量建立索引後使用可以滿足需求,但是也無需求對資料的實時性要求較高,會頻繁更新索引,這時候索引操作就較慢。那麼就有了下面的優化方案。由於mongodb本身不自帶中文全文檢索功能,那麼如何來利用高效的英文全文檢索呢?考慮 英文全文檢索實現就是按照空格劃分內容,例...
MySQL全文檢索中文搜尋
全文檢索概述 檢索基本過程 全文檢索大體分兩個過程,索引建立 indexing 和搜尋索引 search 索引建立 將需要被搜尋的資料提取資訊,建立索引的過程。搜尋索引 就是得到使用者的查詢請求,搜尋建立的索引,然後返回結果的過程。全文檢索的索引建立過程一般有以下幾步 1 準備待索引的原資料 2 將...