Sphinx(以及繼承者 Manticore Search)的索引建立遵循經典的資訊檢索管線架構,每階段負責特定的語言處理任務:
從資料來源(MySQL、PostgreSQL、XML、CSV、JSON、Tsvpipe 等)抽取原始文件。每個文件包含唯一 ID 及多個欄位(標題、內容、標籤、屬性等)。
# sphinx.conf 範例
source my_source {
type = mysql
sql_host = localhost
sql_user = sphinx
sql_pass = secret
sql_db = mydb
sql_query = SELECT id, title, content, category_id, created_at FROM articles
sql_attr_uint = category_id
sql_attr_timestamp = created_at
}
將原始文本切分為最小語義單元(Token)。中文需特殊處理:
index my_index {
source = my_source
path = /var/data/my_index
charset_type = utf-8
ngram_len = 1 # 單字切分(適用混合語言)
# 或使用中文分詞器
# charset_dictpath = /usr/local/sphinx/etc/
# charset_type = zh_CN.utf-8
}
對 Token 進行標準化轉換,提升召回率:
charset_table 定義字元映射morphology = stem_en, stem_ru(英文、俄文等)stopwords = /path/stopwords.txt 過濾「的、是、在」等高頻無意義詞wordforms 映射「手機→手機, 機」exceptions 保護特定詞不被切分(如「C++」)將處理後的 Term 建立倒排索引:
| 類型 | 特點 | 適用場景 |
|---|---|---|
| Plain Index | 批次重建、查詢效能最佳 | 資料變動低、可容忍延遲(每日重建) |
| Real-time (RT) Index | 即時增刪改、查詢稍慢 | 需即時搜尋(評論、即時訊息) |
| Distributed Index | 邏輯聚合多個子索引 | 分散式部署、大規模資料 |
# 批次建立(Plain Index)
indexer --config /etc/sphinx/sphinx.conf --all --rotate
# 僅重建特定索引
indexer --config /etc/sphinx/sphinx.conf my_index --rotate
# RT 索引無需 indexer,透過 SphinxQL 即時寫入
# INSERT INTO rt_index (id, title, content) VALUES (1, '標題', '內容');
mem_limit:索引建立記憶體上限(預設 128M,建議 512M-2G)max_iops / max_iosize:限制磁碟 I/O,避免影響線上服務html_strip:自動移除 HTML 標籤(1/0)index_exact_words:保留原始詞以支援精確匹配(1/0)| 問題 | 原因 | 解決 |
|---|---|---|
| 中文搜不到 | 未設定 ngram 或中文分詞器 | 設定 ngram_len=1 或安裝 jieba/mmseg |
| 索引過大 | ngram 產生大量 Token | 改用詞典分詞、啟用 stopwords、調整 min_word_len |
| 重建太慢 | 資料量大、mem_limit 過小 | 增大 mem_limit、使用分散式索引、增量更新策略 |
| 搜尋不準 | 缺少同義詞、停用詞設定不當 | 配置 wordforms、優化 stopwords、調整 ranker |
index my_index {
# ...
charset_type = utf-8
ngram_len = 1 # 基礎單字切分
ngram_chars = U+3000..U+2FA1F # 擴展 CJK 範圍
# 配合 morphology=none 避免英文被錯切
# 英文單詞靠 ngram=1 自然分隔(空格)
}
Sphinx 索引建立是「離線重度、線上輕度」的典型架構。理解四階段管線,才能針對性優化分詞策略、語言處理規則與索引結構,打造精準高效的搜尋體驗。