文章目錄
- 一、分詞的核心作用
- 二、分詞器(Analyzer):分詞的“執行單元”
- 1. 字符過濾器(Character Filter):預處理原始文本
- 2. 分詞器(Tokenizer):拆分文本為詞元(Token)
- 3. 詞元過濾器(Token Filter):優化詞元
- 三、內置分詞器與自定義分詞器
- 四、中文分詞的特殊性
- 五、關鍵注意事項
- 總結
Elasticsearch(ES)的分詞是全文檢索的核心環節,其本質是將
原始文本(如一句話、一段日誌)拆分成若干個有意義的“詞(Term)”,這些詞會被存入倒排索引,供後續查詢時快速匹配。分詞的質量直接影響檢索的準確性(能否精準匹配)和召回率(能否找到所有相關結果)。
一、分詞的核心作用
在ES中,分詞發生在兩個階段:
- 索引時:當文檔寫入ES時,會對
text類型的字段進行分詞,將拆分後的Term存入倒排索引(記錄Term與文檔的對應關係)。 - 搜索時:用户輸入查詢文本時,ES會對查詢文本執行相同的分詞邏輯,得到Term後,去倒排索引中匹配包含這些Term的文檔。
關鍵原則:索引和搜索時的分詞邏輯必須一致(或兼容),否則會導致“索引的Term”與“搜索的Term”不匹配,查詢不到結果。例如:索引時將“Hello”拆分為小寫“hello”,但搜索時未小寫處理,就會匹配失敗。
二、分詞器(Analyzer):分詞的“執行單元”
ES的分詞由分詞器(Analyzer) 完成,一個分詞器是三個組件的組合,按順序執行:
原始文本 → 字符過濾器(Character Filter) → 分詞器(Tokenizer) → 詞元過濾器(Token Filter) → 最終Term
1. 字符過濾器(Character Filter):預處理原始文本
作用:在文本被拆分前,對原始字符串進行清洗或轉換(如去除無用字符、替換特殊符號)。
- 可配置多個,按順序執行。
- 常見類型:
html_strip:去除HTML標籤(如將<p>hello</p>轉換為hello)。mapping:替換指定字符(如將:-)替換為happy)。pattern_replace:用正則表達式替換(如將數字替換為NUMBER)。
2. 分詞器(Tokenizer):拆分文本為詞元(Token)
作用:將預處理後的文本按規則拆分成若干個“詞元(Token)”(尚未最終存入索引的臨時詞),是分詞的核心步驟。
- 一個分詞器必須且只能有一個Tokenizer。
- 拆分規則由Tokenizer的類型決定,例如:
- Standard Tokenizer(默認):按Unicode文本分割規則拆分(空格、標點、符號等視為分隔符),並去除大部分標點。
例:"Hello, world! 123"→ 拆分為["Hello", "world", "123"]。 - Whitespace Tokenizer:僅按空格拆分,保留標點。
例:"Hello, world! 123"→ 拆分為["Hello,", "world!", "123"]。 - Letter Tokenizer:僅按非字母字符拆分(只保留字母組成的詞)。
例:"Hello, world! 123"→ 拆分為["Hello", "world"](數字和標點被當作分隔符)。 - 中文分詞器(如IK Tokenizer):針對中文無空格的特點,按語義拆分(基於詞典和規則)。
例:"我愛北京天安門"→ 拆分為["我", "愛", "北京", "天安門"]。
3. 詞元過濾器(Token Filter):優化詞元
作用:對Tokenizer輸出的詞元進行二次處理(如過濾、轉換、增刪),最終生成存入索引的Term。
- 可配置多個,按順序執行。
- 常見類型:
lowercase:將詞元轉為小寫(解決大小寫不敏感問題)。
例:["Hello", "World"]→ 轉為["hello", "world"]。stop:去除停用詞(無實際意義的詞,如“的”“a”“the”)。
例:["我", "的", "北京"]→ 過濾後["我", "北京"]。synonym:替換同義詞(提升召回率)。
例:配置“西紅柿→番茄”,則["西紅柿"]→ 轉為["番茄", "西紅柿"](同時保留原詞和同義詞)。stemmer:詞幹提取(將動詞變體轉為原型,如“running”→“run”)。
三、內置分詞器與自定義分詞器
ES提供了多種內置分詞器(已組合好Character Filter、Tokenizer、Token Filter),滿足常見場景:
standard(默認):Standard Tokenizer + lowercase + stop(默認去除英文停用詞)。simple:Letter Tokenizer + lowercase(只保留字母並小寫)。whitespace:僅Whitespace Tokenizer(按空格拆分,不做其他處理)。keyword:特殊分詞器,不拆分文本(將整個文本作為一個Term,類似keyword類型的字段)。
如果內置分詞器不滿足需求(如中文分詞、自定義規則),可自定義分詞器,例如:
// 定義一箇中文分詞器(使用IK分詞+小寫轉換+過濾停用詞)
"settings": {
"analysis": {
"analyzer": {
"my_ik_analyzer": { // 自定義分詞器名稱
"type": "custom",
"char_filter": [], // 無字符過濾
"tokenizer": "ik_max_word", // IK分詞器(細粒度拆分)
"filter": ["lowercase", "stop"] // 轉小寫+過濾停用詞
}
}
}
}
四、中文分詞的特殊性
英文等語言天然以空格分隔單詞,分詞規則簡單;但中文無空格,且存在“一詞多義”“歧義”(如“南京市長江大橋”可拆分為“南京市/長江大橋”或“南京/市長/江大橋”),因此需要專門的中文分詞器:
- IK分詞器:最常用的中文分詞器,支持“ik_smart”(粗粒度拆分,適合精準匹配)和“ik_max_word”(細粒度拆分,適合召回率優先)。
- Jieba分詞器:基於Python的分詞庫,ES可通過插件集成,支持自定義詞典和新詞發現。
- THULAC:清華大學開源的分詞工具,精度較高,但性能略低。
中文分詞的核心是詞典+規則+模型:
- 詞典:內置常用詞庫(如“北京”“天安門”),確保已知詞正確拆分。
- 規則:處理未登錄詞(詞典中沒有的詞,如網絡新詞“內卷”)。
- 模型:部分分詞器結合機器學習模型(如BERT),解決歧義問題(如通過上下文判斷拆分方式)。
五、關鍵注意事項
- 字段類型與分詞:
text類型:會被分詞,用於全文檢索。keyword類型:不分詞(整個字段作為一個Term),用於精確匹配、排序、聚合。
(建議對text字段同時設置keyword子字段,如name.keyword,兼顧檢索和聚合)。
- 索引與搜索分詞器一致性:
- 索引時用
analyzer(默認與字段配置一致),搜索時用search_analyzer(默認與analyzer相同)。 - 若需特殊處理(如搜索時用更粗粒度的分詞),可單獨配置
search_analyzer。
- 分詞效果測試:
可通過ES的_analyzeAPI測試分詞結果,驗證是否符合預期:
GET /_analyze
{
"analyzer": "ik_max_word",
"text": "我愛北京天安門"
}
總結
ES的分詞是“文本預處理→拆分→優化”的流水線過程,核心是通過分詞器將文本轉化為可檢索的Term。合理配置分詞器(尤其是中文場景)是提升檢索效果的關鍵——既需要準確拆分有意義的詞,又要通過過濾、同義詞等處理平衡“精準度”和“召回率”。