Elasticsearch分析器
無(wú)論是內(nèi)置的分析器(analyzer)屑埋,還是自定義的分析器(analyzer)咪笑,都是由字符過(guò)濾器(character filters)上鞠、分詞器(tokenizers) 和 token過(guò)濾器( token filters)組成妓羊。char_filter是字符過(guò)濾器驾讲,filter是token filter郎仆。
字符過(guò)濾器(character filters)
字符過(guò)濾器以字符流的形式接受原始文本只祠,并可以通過(guò)增加、刪除和更改字符來(lái)轉(zhuǎn)換字符流扰肌。分詞之前預(yù)處理抛寝。
一個(gè)analyzer可以有0個(gè)或者多個(gè)character filters。
-
HTML字符過(guò)濾器(HTML Strip Character Filter): html_strip表示提出html標(biāo)簽曙旭;escaped_tags表示保留html標(biāo)簽盗舰。
# my_char_filter:自定義char_filter,剔除除<a>標(biāo)簽外的所有的html標(biāo)簽 # tokenizer:keyword keyword分詞器:整個(gè)輸入作為一個(gè)單獨(dú)詞匯單元桂躏,方便特殊類型的文本進(jìn)行索引和檢索钻趋。針對(duì)郵政編碼,地址等文本信息使用關(guān)鍵詞分詞器進(jìn)行索引項(xiàng)建立非常方便 # my_analyzer:自定義分析器 DELETE my_index PUT my_index { "settings": { "analysis": { "char_filter": { "my_char_filter":{ "type":"html_strip", "escaped_tags": ["a"] } } , "analyzer": { "my_analyzer":{ "tokenizer":"keyword", "char_filter":"my_char_filter" } } } } } POST my_index/_analyze { "analyzer": "my_analyzer", "text": "<p>I'm so <a>happy</a>!</p>" } { "tokens" : [ { // 過(guò)濾之后的結(jié)果 "token" : """ I'm so <a>happy</a>! """, "start_offset" : 0, "end_offset" : 32, "type" : "word", "position" : 0 } ] }
-
映射字符過(guò)濾器(Mapping Character Filter): type -> mapping 字符映射
# my_char_filter:自定義char_filter剂习,利用type=mapping進(jìn)行字符替換 # tokenizer:keyword keyword分詞器:整個(gè)輸入作為一個(gè)單獨(dú)詞匯單元蛮位,方便特殊類型的文本進(jìn)行索引和檢索。針對(duì)郵政編碼鳞绕,地址等文本信息使用關(guān)鍵詞分詞器進(jìn)行索引項(xiàng)建立非常方便 # my_analyzer:自定義分析器 DELETE my_index PUT my_index { "char_filter": { "my_char_filter": { "type": "mapping", "mappings": [ "? => 0", "? => 1", "? => 2", "? => 3", "? => 4", "? => 5", "? => 6", "? => 7", "? => 8", "? => 9" ] } }, "settings": { "analysis": { "analyzer": { "my_analyzer": { "tokenizer": "keyword", "char_filter": [ "my_char_filter" ] } } } } } POST my_index/_analyze { "analyzer": "my_analyzer", "text": "My license plate is ?????" } { "tokens" : [ { "token" : "My license plate is 25015", "start_offset" : 0, "end_offset" : 25, "type" : "word", "position" : 0 } ] }
-
模式替換過(guò)濾器(Patten Replace Character Filter): type -> patten_replace 正則匹配
DELETE my_index # my_analyzer:自定義模式匹配分析器失仁,正則匹配上的字符串將不再分詞 PUT my_index { "settings": { "analysis": { "analyzer": { "my_analyzer": { "tokenizer": "standard", "char_filter": ["my_char_filter"] } }, "char_filter": { "my_char_filter": { "type": "pattern_replace", "pattern": "(\\d+)-(?=\\d)", "replacement": "$1_" } } } } } POST my_index/_analyze { "analyzer": "my_analyzer", "text": "My credit card is 123-456-789" } { "tokens" : [ { "token" : "My", "start_offset" : 0, "end_offset" : 2, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "credit", "start_offset" : 3, "end_offset" : 9, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "card", "start_offset" : 10, "end_offset" : 14, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "is", "start_offset" : 15, "end_offset" : 17, "type" : "<ALPHANUM>", "position" : 3 }, { "token" : "123_456_789", "start_offset" : 18, "end_offset" : 29, "type" : "<NUM>", "position" : 4 } ] }
分詞器(Tokenizer)
一個(gè)分詞器接受一個(gè)字符流,并將其拆分成單個(gè)token(通常是單個(gè)單詞)们何,并輸出一個(gè)token流萄焦。
Tokenizer負(fù)責(zé)將文本拆分成單個(gè)token(一個(gè)一個(gè)的單詞,這些單詞叫token)冤竹,就是一段文本被分隔成好幾部分拂封,相當(dāng)于java的split。
分詞器負(fù)責(zé)記錄每個(gè)term的書(shū)序或位置鹦蠕,以及term所表示的原單詞的開(kāi)始和結(jié)束字符偏移量(文本被分詞后的輸出是一個(gè)term數(shù)組)冒签。
一個(gè)分析器必須只能一個(gè)分詞器
ES內(nèi)置分詞器 7.6 15種 自帶分詞器
① standard analyzer:默認(rèn)分詞器,中文支持的不理想钟病,會(huì)逐字拆分萧恕。
1) max_token_length:最大令牌長(zhǎng)度霜定。如果看到令牌超過(guò)此長(zhǎng)度,則將其max_token_length間隔分割廊鸥。默認(rèn)為255望浩。
② Pattern Tokenizer:以正則匹配分隔符,把文本拆分成若干詞項(xiàng)惰说。
③ Simple Pattern Tokenizer:以正則匹配詞項(xiàng)磨德,速度比Pattern Tokenizer快。
④ whitespace analyzer:以空白符分隔 Tim_cookie-
代碼樣例:
#設(shè)置type為custom告訴Elasticsearch我們正在定義一個(gè)定制分析器吆视。將此與配置內(nèi)置分析器的方式進(jìn)行比較: type將設(shè)置為內(nèi)置分析器的名稱典挑,如 standard或simple # 自定義字符過(guò)濾器 test_char_filter ,將 & 替換為 and | 替換為 or # 自定義token filter啦吧, 停用詞 is您觉、in、at授滓、the琳水、a、for # 分詞器增加標(biāo)點(diǎn)過(guò)濾:模式匹配般堆,去除 .,!? 四種標(biāo)點(diǎn)符號(hào) # 自定義分析器 my_analyzer 匯總以上三種自定義在孝,同時(shí)character filter增加提出html,token filter 增加 字母小寫(xiě)淮摔。 PUT /test_analysis { "settings": { "analysis": { "char_filter": { "test_char_filter": { "type": "mapping", "mappings": [ "& => and", "| => or" ] } }, "filter": { "test_stopwords": { "type": "stop", "stopwords": ["is","in","at","the","a","for"] } }, "tokenizer": { "punctuation": { "type": "pattern", "pattern": "[ .,!?]" } }, "analyzer": { "my_analyzer": { "type": "custom", "char_filter": [ "html_strip", "test_char_filter" ], "tokenizer": "standard", "filter": ["lowercase","test_stopwords"] } } } } } GET /test_analysis/_analyze { "text": "Teacher ma & zhang also thinks [mother's friends] is good | nice!!!", "analyzer": "my_analyzer" } # 執(zhí)行結(jié)果 { "tokens" : [ { "token" : "teacher", "start_offset" : 0, "end_offset" : 7, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "ma", "start_offset" : 8, "end_offset" : 10, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "and", "start_offset" : 11, "end_offset" : 12, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "zhang", "start_offset" : 13, "end_offset" : 18, "type" : "<ALPHANUM>", "position" : 3 }, { "token" : "also", "start_offset" : 19, "end_offset" : 23, "type" : "<ALPHANUM>", "position" : 4 }, { "token" : "thinks", "start_offset" : 24, "end_offset" : 30, "type" : "<ALPHANUM>", "position" : 5 }, { "token" : "mother's", "start_offset" : 32, "end_offset" : 40, "type" : "<ALPHANUM>", "position" : 6 }, { "token" : "friends", "start_offset" : 41, "end_offset" : 48, "type" : "<ALPHANUM>", "position" : 7 }, { "token" : "good", "start_offset" : 53, "end_offset" : 57, "type" : "<ALPHANUM>", "position" : 9 }, { "token" : "or", "start_offset" : 58, "end_offset" : 59, "type" : "<ALPHANUM>", "position" : 10 }, { "token" : "nice", "start_offset" : 60, "end_offset" : 64, "type" : "<ALPHANUM>", "position" : 11 } ] }
Token過(guò)濾器(token filters)
token filters接受token流私沮,并且可能會(huì)增加、刪除或者更改token流和橙;
不允許token過(guò)濾器更改每個(gè)token的位置和字符偏移仔燕。
一個(gè)分詞器可能有0個(gè)或者多個(gè)token過(guò)濾器,它們按照順序應(yīng)用魔招。
一般負(fù)責(zé)時(shí)態(tài)轉(zhuǎn)換晰搀、大小寫(xiě)轉(zhuǎn)換、同義詞轉(zhuǎn)換仆百、語(yǔ)氣詞處理等厕隧。比如 has=>have him=>he apples=>apple the/oh/a=>干掉
-
代碼樣例-1:
DELETE my_index # setting 設(shè)置索引配置 # my_token_filter:自定義token過(guò)濾器奔脐,1~20個(gè)字符詞條才會(huì)被搜索 # my_analyzer:自定義分析器俄周;使用的token過(guò)濾器有:lowercase(系統(tǒng)) 和 my_token_filter(自定義) # type:custom 固定寫(xiě)法,表示自定義分析器 # tokenizer:standard 系統(tǒng)自帶的分詞器髓迎。 # mappings中定義字段映射峦朗,使用自定義的分析器。 # analyzer 指的是在建索引時(shí)的分詞策略 # search_analyzer 指的是在查詢時(shí)的分詞策略 PUT my_index { "settings": { "analysis": { "filter": { "my_token_filter":{ "type":"edge_ngram", "min_gram":1, "max_gram":20 } } , "analyzer": { "my_analyzer":{ "type":"custom", "tokenizer":"standard", "filter":[ "lowercase", "my_token_filter" ] } } } } , "mappings": { "properties": { "keyword":{ "type": "text" , "analyzer": "my_analyzer" , "search_analyzer": "standard" } } } }
-
代碼樣例-2:
# 利用stardard 將文本分詞之后的所有token進(jìn)行小寫(xiě)排龄。 GET _analyze { "tokenizer" : "standard", "filter" : ["lowercase"], "text" : "THE Quick FoX JUMPs" } # 自定義條件token過(guò)濾器 GET /_analyze { "tokenizer":"standard", "filter": [ { "type": "condition", "filter": [ "lowercase" ], "script": { "source": "token.getTerm().length() < 5" } } ], "text": "THE QUICK BROWN FOX" }
-
代碼樣例-3:
# 自定義分析器波势,采用英語(yǔ)內(nèi)置的stopword(停用詞) PUT /my_index { "settings": { "analysis": { "analyzer": { "my_analyzer":{ "type":"standard", "stopwords":"_english_" } } } } } GET my_index/_analyze { "analyzer": "my_analyzer", "text": "Teacher Ma is in the restroom" }
停用詞:
停用詞過(guò)濾:是文本分析中一個(gè)預(yù)處理方法。它的功能是過(guò)濾分詞結(jié)果中的噪聲(例如:的、是尺铣、啊等)
停用詞:指在信息檢索中拴曲,為節(jié)省存儲(chǔ)空間和提高搜索效率,在處理自然語(yǔ)言數(shù)據(jù)(或文本)之前或之后會(huì)自動(dòng)過(guò)濾掉某些字或詞凛忿,這些字或詞即被稱為Stop Words(停用詞)澈灼。這些停用詞都是人工輸入、非自動(dòng)化生成的店溢,生成后的停用詞會(huì)形成一個(gè)停用詞表叁熔。但是,并沒(méi)有一個(gè)明確的停用詞表能夠適用于所有的工具床牧。甚至有一些工具是明確地避免使用停用詞來(lái)支持短語(yǔ)搜索的荣回。
移除停用詞的工作是由stop停用詞過(guò)濾器完成的,可以通過(guò)創(chuàng)建自定義分析器來(lái)使用它戈咳。但是也有一些自帶的分析器預(yù)制使用停用詞過(guò)濾器
-
語(yǔ)言分析器:每個(gè)語(yǔ)言分析器默認(rèn)使用 該語(yǔ)言相適應(yīng)的停用詞列表心软。特定語(yǔ)言的默認(rèn)停用詞,可以通過(guò)使用
_lang_
符號(hào)來(lái)指定著蛙。如 english 英語(yǔ)分析器使用 :_english_ 停用詞列表糯累。"stopwords": "_english_";# 默認(rèn)的停用詞是 _english_ # 本例通過(guò) _none_ 禁用了停用詞 PUT /my_index { "settings": { "analysis": { "analyzer": { "my_english": { "type": "english", "stopwords": "_none_" } } } } } # 停用詞 可以指定路徑 # 停用詞文件的路徑册踩,該路徑相對(duì)于 Elasticsearch 的 config 目錄 PUT /my_index { "settings": { "analysis": { "analyzer": { "my_english": { "type": "english", "stopwords_path": "stopwords/english.txt" } } } } }
-
standard 標(biāo)準(zhǔn)分析器:默認(rèn)使用空的停用詞列表:_none_泳姐,實(shí)際是禁用了停用詞。
# 自定義分析器 my_analyzer # 標(biāo)準(zhǔn)的standard分析器暂吉,進(jìn)行了一些自定義配置 # 過(guò)濾掉停用詞 and 和 the PUT /my_index { "settings": { "analysis": { "analyzer": { "my_analyzer": { "type": "standard", "stopwords": [ "and", "the" ] } } } } }
- pattern模式分析器:與standard分析器類似胖秒,默認(rèn)使用空的的停用詞里誒博愛(ài):為_(kāi)none_。
分詞器(analyzer)處理過(guò)程
搜索引擎的人性化(Normalization)
為key_words提供更加完整的倒排索引慕的。
如:時(shí)態(tài)轉(zhuǎn)化(like | liked)阎肝,單復(fù)數(shù)轉(zhuǎn)化(man | men),全寫(xiě)簡(jiǎn)寫(xiě)(china | cn)肮街,同義詞(small | little)等风题。
如:china 搜索時(shí),如果條件為cn是否可搜索到嫉父。
如:dogs沛硅,搜索時(shí),條件為dog是否可搜索到數(shù)據(jù)绕辖。
如果可以使用簡(jiǎn)寫(xiě)(cn)或者單復(fù)數(shù)(dog&dogs)搜索到想要的結(jié)果摇肌,那么稱為搜索引擎normalization人性化。
normalization是為了提升召回率的(recall)仪际,就是提升搜索能力的围小。
normalization是配合分詞器(analyzer)完成其功能的昵骤。
分詞器的功能就是處理Document中的field的。就是創(chuàng)建倒排索引過(guò)程中用于切分field數(shù)據(jù)的肯适。
如:I think dogs is human’s best friend.在創(chuàng)建倒排索引的時(shí)候变秦,使用分詞器實(shí)現(xiàn)數(shù)據(jù)的切分。
上述的語(yǔ)句切分成若干的詞條框舔,分別是: think dog human best friend伴栓。
常見(jiàn)搜索條件有:think、 human雨饺、 best钳垮、 friend,很少使用is额港、a饺窿、the、i這些數(shù)據(jù)作為搜索條件移斩。