[SQL SERVER]提高SQL SERVER全文檢索搜尋準確度
SQL2005後版本全文檢索都有中文斷詞導致找不到資料情況,
這樣更改主要是因為效能考量,80/20原則來看這項投資其實很值得,
而要彌補搜尋資料準確度那20%就得自行手動調整(就我個人認為避免不了),
這篇記錄整個過程,好讓有同樣困擾的朋友有個參考,
也加強自己印象。
建立測試資料表
Create Table MyFTSearch
(
id int identity(1,1) not null,
text_to_search nvarchar(max)
);
alter table MyFTSearch add constraint PK_MyFTSearch primary key(id)
insert into MyFTSearch select N'三分天下,伯仲之間,諸葛亮臥龍先生,桃園三結義劉關張留官章
關雲長關公關羽手拿青龍偃月刀,常勝將軍趙子龍趙雲,百萬中單騎救少主
三國志-陳壽,張飛丈八蛇矛,出身未捷身先死,常使英雄淚滿襟'
建立全文檢索目錄
CREATE FULLTEXT CATALOG MyFTSearchFTS
WITH ACCENT_SENSITIVITY = OFF
建立全文檢索索引
CREATE FULLTEXT INDEX ON MyFTSearch
(text_to_search LANGUAGE 1028)
KEY INDEX PK_MyFTSearch
ON MyFTSearchFTS
WITH STOPLIST = OFF
啟動
ALTER FULLTEXT INDEX ON MyFTSearch enable
查看斷詞關鍵字結果
SELECT display_term, column_id, document_count
FROM sys.dm_fts_index_keywords
(DB_ID('mobile'), OBJECT_ID('MyFTSearch'))
(擷取部分)可以看到斷詞工具並非以字為單位。
查詢 園三結 會找不到資料
SELECT *
FROM MyFTSearch
WHERE CONTAINS(text_to_search, '*園三結*');
桃園三結義劉關張留官章 被斷詞工具處理如下
桃園
三
結義
劉
關
張
留
官
章
所以我搜尋以下關鍵字都可以找到結果
SELECT *
FROM MyFTSearch
WHERE CONTAINS(text_to_search, '*劉*');
SELECT *
FROM MyFTSearch
WHERE CONTAINS(text_to_search, '*關張*');
SELECT *
FROM MyFTSearch
WHERE CONTAINS(text_to_search, '*桃園*');
SELECT *
FROM MyFTSearch
WHERE CONTAINS(text_to_search, '*留官章*');
提高搜尋準確度,我目前作法如[Search Server]改善使用者搜尋經驗(四)一文,
使用替換或擴充會比較符合現實世界,
因為你無須重新擴展全文檢索索引(SQL2008),只需重新載入同義字檔案就可即時反應結果,
但這動作避免不了人工手動介入,
想要避免這過程,可能只能透過第三方斷詞工具(字為單位)替換SQL SERVER斷詞工具的方式,
但以字為單位的斷詞工具就會有效能問題,我個人感覺目前沒有兩全其美的方法,
凡事都要有所取捨(80/20原則),下面我透過擴充集來解決 "園三結" 關鍵字。
ps:如有好的斷詞工具(字為單位兼具效能)請在告訴我
修改tscht.xml
預設路徑C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2K8R2\MSSQL\FTData
修改完後重新載入同義字檔案
EXEC sys.sp_fulltext_load_thesaurus_file 1028 (SQL2005須重新啟動全文檢索)
如果載入檔案發生錯誤可參考下面解決方法
無法載入 SQL Server 的同義字檔案,並且您會收到下列錯誤訊息: 「 ERROR_INTERNAL_DB_CORRUPTION 」
再次查詢 園三結
--透過同義字檔案
SELECT *
FROM MyFTSearch
WHERE CONTAINS(text_to_search,'FORMSOF(THESAURUS,園三結)')
參考