本文記錄一個完整的輕量級全文搜尋引擎構建過程:後端採用 MySQL 5.6+ InnoDB 原生 Fulltext 索引 + C 語言 DLL 高效查詢,中間層以 C# WCF 服務暴露 JSON API,前端用 jQuery UI Autocomplete 實現即時搜尋建議與結果展示。
[瀏覽器 jQuery UI]
↓ AJAX/JSON
[C# WCF Service (VisionWeb)]
↓ P/Invoke
[C DLL (VisionDAL) + libmysql.dll]
↓ MySQL Protocol
[MySQL 5.6 InnoDB Fulltext]
CREATE TABLE `document` (
`DocumentID` INT NOT NULL AUTO_INCREMENT,
`Title` VARCHAR(255),
`Text` TEXT,
PRIMARY KEY (`DocumentID`),
FULLTEXT KEY `ft` (`Title`, `Text`), -- 全文搜尋索引
FULLTEXT KEY `ftTitle` (`Title`) -- 自動完成專用索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
關鍵點: InnoDB Fulltext 支援中文分詞 (需配置 ngram 解析器或 5.7+ 內建);建立兩個索引分離「全文檢索」與「標題補全」場景。
MYSQL *Connect() {
MYSQL *conn = mysql_init(NULL);
if (!mysql_real_connect(conn, host, user, pass, db, port, NULL, 0)) return NULL;
mysql_query(conn, "SET NAMES 'utf8'");
return conn;
}
// 自動完成:僅搜 Title,回傳 Title + 分數
wsprintf(query, L"SELECT Title, MATCH(Title) AGAINST('%ls' IN BOOLEAN MODE) AS Score
FROM Document WHERE MATCH(Title) AGAINST('%ls' IN BOOLEAN MODE) > 0.001
ORDER BY Score DESC LIMIT 20", search, search);
// 全文搜尋:搜 Title+Text,回傳完整文檔
wsprintf(query, L"SELECT DocumentID, Title, Text,
MATCH(Title, Text) AGAINST('%ls' IN BOOLEAN MODE) AS Score
FROM Document WHERE MATCH(Title, Text) AGAINST('%ls' IN BOOLEAN MODE) > 0.001
ORDER BY Score DESC", search, search);
Boolean Mode 技巧: 支援 * 通配符 (如 as* 匹配 asp)、+ 必含、- 排除、"" 精確短語。
使用 mysql_store_result + mysql_fetch_row 迭代,MultiByteToWideChar 處理 UTF-8 ↔ UTF-16 轉換,手動拼接 JSON 字串 (避免引入第三方庫)。
[ServiceContract]
public interface IVisionService {
[OperationContract]
[WebInvoke(Method="POST", BodyStyle=WebMessageBodyStyle.WrappedRequest,
RequestFormat=WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json)]
string GetDocuments(string search, int format, int forAutocomplete);
}
public class VisionService : IVisionService {
[DllImport("VisionDAL.dll", CharSet=CharSet.Unicode)]
public static extern string GetDocuments(string search, int format, int forAutocomplete);
// 直接透傳
}
Web.config 關鍵: webHttpBinding + webHttpEndpoint 啟用 REST/JSON;crossDomainScriptAccessEnabled 支援跨域。
$("#search").autocomplete({
source: function(request, callback) {
// 同步 AJAX 取建議詞
$.ajax({ url: svcUrl, data: {search: term, format:1, forAutocomplete:1},
async: false, success: function(json) { callback(JSON.parse(json)); } });
}
});
$.ajax({
type: 'POST', url: svcUrl, dataType: 'json',
data: JSON.stringify({search: term + '*', format: 1, forAutocomplete: 0}),
success: function(json) { renderTable(JSON.parse(json)); }
});
VisionDAL.dll。VisionDAL.dll、libmysql.dll 目錄加入系統 PATH。secure_file_priv、防火牆、local_infile 不干擾。innodb_ft_min_token_size、ngram_token_size 優化中文分詞粒度。專案結構參考: VisionDAL (C DLL) → VisionWeb (WCF) → Default.html (jQuery UI) → MySQL (InnoDB Fulltext)。完整代碼可作為企業內部知識庫、工單系統搜尋模組的起點。