沒有人會質疑 Google 搜尋引擎的威力吧。事實上,Google 搜尋引擎做得最好的,就是能針對使用者下的 full-text query,在極短時間內,從非常大量的網路文件庫中,找出(並排序)「最有可能滿足使用者 query」的文件(URL、摘要、以及庫存檔)。
而實驗室既然想做一套「古契書的檢索系統」,當然也得提供全文檢索的功能。不過,現實面上,很容易就會處於抉擇的難點。難以抉擇的地方在哪兒呢?原來,我們的系統,並不只是想提供全文檢索,還希望利用其他的 metadata(好像是翻譯為「詮釋資料」吧)來增進檢索的效能。
於是,系統可能就得整合一套關連式資料庫 (RDDB)、與一套全文檢索系統(例如,Apache 的 Lucene project)。「整合」總是件吃力卻不怎麼討好的工作。
雖然 Microsoft SQL Server 很早就有同時提供 RDDB 與 full-text retrieval 的功能,但是實驗室老闆是很討厭 M$ 的;Oracle 有很好的 RDDB,但全文索引不是內建;因此,腦筋通常都會動到開放原始碼的 MySQL 上。
很高興地看見,MySQL 文件上,說它是支援全文檢索的。不過,實際跑了跑,就會有些沮喪:對中文資料而言,似乎行不通。手冊、甚至是網路文件上,對於如何處理中文的全文檢索,雖有片段的說明,卻缺乏完整的實例。
好吧,這又是一個需要做實驗(測試、並嘗試找到解答)的地方。「實驗室」嘛,就是得做做實驗,不是嗎?
透過以下這些步驟,應該可以讓 MySQL 處理中文的全文檢索:
- 資料庫採用 UTF-8 編碼格式,以支援中文。此外,欲提供全文檢索,資料表必須採用 MyISAM 的型態。例如,CREATE TABLE table_name (...) ENGINE=MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;。
- 在資料表內建立欄位的全文索引。由於 MySQL 並不支援中文的斷字,因此我們目前還得新增一個欄位來儲存輔助全文檢索。例如,假設我們想對 DOC 欄位做全文索引,那麼除了 DOC 之外,我們還得新增一個(名稱自取的)DOC_FOR_FULLTEXT 欄位。然後,在 CREATE TABLE 時,加入 FULLTEXT (DOC_FOR_FULLTEXT) 來對這個輔助欄位的資料,建立全文索引。
- 將全文資料填入 DOC 欄位時,也將「自行斷字處理後的文件字串」填到 DOC_FOR_FULLTEXT 欄位裡。例如,假設要填入 DOC 欄位的全文是"新竹縣東興庄",那我們也同時將斷字後的 "新 竹 縣 東 興 庄 "(註:若字串內容為 UTF-16 Little Endian 編碼,利用 PHP 的 chunk_split() 可以在字串內,每隔兩個 bytes 插入一個空白字元 "\x20\0")填入 DOC_FOR_FULLTEXT 欄位。
- 執行 full-text SQL query 前,先執行 SET NAMES 'utf8'
- full-text SQL query 長得像這副模樣: SELECT * FROM
WHERE MATCH (DOC_FOR_FULLTEXT) AGAINST ($fulltext_query IN BOOLEAN MODE) 。其中,$fulltext_query 是一個對 user query 做過處理的字串。例如,若使用者輸入「新竹」,則 $fulltext_query 需要被處理為「'"新 竹"'」(注意:「新」與「竹」之間要有空白斷開,「新 竹」要用單引號框住雙引號;還有,不要忘記,SQL query 必須以 UTF-8 編碼的)。
4 則留言:
用英文的檢索來檢索中文是有許多阿里不達的小麻煩的...而且還有近似搜尋的問題....還有詞的問題, 中研院的斷詞詞庫"應該"沒包括古契書的詞....
反正, 剛開始的時候, 一定是撈到一票不要的東西, 還要多一次處理來過濾, 接下來就是針對過濾的部份來增加資料庫的欄位....
哈哈,「用英文的檢索來檢索中文是有許多阿里不達的小麻煩的」,說得真夠貼切。
不過,有這麼多麻煩,那要不要自己開發中文的檢索系統?嗯... 這需要有「非常強大」的後援,我看還是算了吧。
想到 MPH 說:「現在這個年紀,唉,算了吧,正事要緊」還真是感慨良多~
呵, 很多人做過這樣的努力, 但都失敗了. 原因之一, 基本的功能可能都比不上 google...原因之二, 很多麻煩是扯到特定的需求, 例如你可能會有名詞演變的問題(例如 基隆雞籠, 但不是同音的問題).
所以找一個全文檢索配合資料庫是個不錯的做法, 雖然時間不見得比較快, 可是看得到未來的路...我現在比較感興趣的是google desktop....
1.請問斷字 DOC_FOR_FULLTEXT
的意思是要把每個中文字 都拆解成一個一個單字嗎?
2.搜尋時 也將搜尋字 拆解成一個一個單字?
張貼留言