關於分析器
ES中默認使用的是標准分析器(standard analyzer)。如果需要對某個字段使用其他分析器,可以在映射中該字段下說明。例如:
PUT /my_index { "mappings": { "blog": { "properties": { "title": { "type": "string", "fields": { "english": { "type": "string", "analyzer": "english" } } } } } } }
在上面:
主 title
字段使用 `standard`(標准)分析器。
title.english 子字段使用 `english`(英語)分析器。
關於自定義分析器
自定義分析器基於標准分析器(或其他ES已有的分析器),通過搭配字符過濾器、分詞器和詞單元過濾器,添加特定的配置,達到提高查詢效果的作用。
1 字符過濾器
很多時候,我們需要處理的文本會是除了干凈文本之外的任何文本。例如HTML文本直接進行分詞會得到糟糕的效果。因此在分詞之前整理文本會提升輸出結果的質量。
HTML分詞
業務不涉及,略
整理標點符號
可能也不需要。
2 分詞器
standard 分詞器使用 Unicode 文本分割算法。它是大多數語言分詞的一個合理的起點,特別是西方語言。
3 詞匯單元過濾器
值得注意的是,當使用多個過濾器,過濾器的先后順序是有考究的。每一個語匯單元過濾器都可以處理來自上一個語匯單元過濾器輸出的單詞流。
3.1 歸一化詞元可以用的過濾器
PUT /my_index { "settings": { "analysis": { "analyzer": { "folding": { "tokenizer": "standard", "filter": [ "lowercase", "asciifolding" ] } } } } }
上面代碼中為自定義分析器folding配置了兩個過濾器lowercase過濾器和asciifolding過濾器。它們的具體功能,以及其他歸一化詞元過濾器將在下面一一介紹。
類似的,若需要配置其他過濾器,只需要在filter字段的列表中添加其他過濾器的名稱。
lowercase過濾器
將接收的詞元歸一化為小寫。
acciifolding過濾器
它不僅僅能去掉變音符號。如果文本是純英語,不包含法語、德語啥的,也可以不考慮這個過濾器
3.2 詞干提取器
3.2.1 基於算法的英文詞干提取器
提供了一系列規則用於將一個詞提取為它的詞根形式,例如剝離復數詞末尾的 s
或 es
。提取單詞詞干時並不需要知道該詞的任何信息。
詞干弱提取 就是無法將同樣意思的單詞縮減為同一個詞根。例如, jumped
和 jumps
可能被提取為 jump
, 但是 jumping
可能被提取為 jumpi
。弱詞干提取會導致搜索時無法返回相關文檔。
詞干過度提取 就是無法將不同含義的單詞分開。例如, general
和 generate
可能都被提取為 gener
。 詞干過度提取會降低精准度:不相干的文檔會在不需要他們返回的時候返回。
DEMO:
# English分析器配置文件,配置文件展示如下: { "settings": { "analysis": { "filter": { "english_stop": { "type": "stop", "stopwords": "_english_" }, "english_keywords": { "type": "keyword_marker", "keywords": [] }, "english_stemmer": { "type": "stemmer", "language": "english" }, "english_possessive_stemmer": { "type": "stemmer", "language": "possessive_english" } }, "analyzer": { "english": { "tokenizer": "standard", "filter": [ "english_possessive_stemmer", "lowercase", "english_stop", "english_keywords", "english_stemmer" ] } } } } } # keyword_marker 分詞過濾器列出那些不用被詞干提取的單詞。這個過濾器默認情況下是一個空的列表。 # english 分析器使用了兩個詞干提取器: possessive_english 詞干提取器和 english 詞干提取器。 # 所有格詞干提取器會在任何詞傳遞到 english_stop 、 english_keywords 和 english_stemmer 之前去除 's 。
常見的基於算法的詞干提取器
3.2.2 基於字典的英文詞干提取器
只是簡單地在字典里查找詞。理論上可以給出比算法化詞干提取器更好的結果,但,實踐中一個好的算法詞干提取器一般優於一個字典詞干提取器。
3.3 停用詞過濾器
停用詞是什么
停用詞是可以將日常使用頻率較高而沒有辨識度的詞,例如:I, and, it等等。
過濾掉停用詞的好處
過濾掉停用詞的最主要好處是提高性能。如果我們不過濾掉停用詞,當我們的檢索詞中包括停用詞"the",如:“the oil field”,由於幾乎所有文檔都會包含“the”這個詞,ES會為幾乎所有文章進行評分,然后倒序排列,取Top N返回。相反,當我們使用停用詞過濾器,“the”會被過濾,ES只會對匹配“oil”和“field”的文檔進行評分、排序等。
如何在自定義分析器中啟用停用詞過濾器
標准分析器是不啟用停用詞過濾器的。我們可以自定義一個分析器my_analyzer,搭配使用標准分析器和停用詞過濾器。
PUT /my_index { "settings": { "analysis": { "analyzer": { "my_analyzer": { "type": "standard", "stopwords": [ "and", "the" ] } } } } }
上面“stopwords”屬性的值是一個包含兩個停用詞(“and”和“the”)的停用詞列表。這個列表也可以替換成“_某語言_”的形式,來指定使用該語言在ES中默認的停用詞表。如:
"stopwords":"_english_"
我們也可以使用自定義停用詞表。將自定義的停用詞以一行一個單詞的格式保存在文件中,此文件必須在集群的所有節點上,並且通過 stopwords_path
參數設置路徑:
PUT /my_index { "settings": { "analysis": { "analyzer": { "my_english": { "type": "english", "stopwords_path": "stopwords/english.txt" # 停用詞文件的路徑,該路徑相對於 Elasticsearch 的 config 目錄 } } } } }