關於ElasticSearch中分析器、分詞器等相關知識的總結
-
分析器(Analyzer)
在說分詞器(Tokenizers)之前,需要了解一個很重要的概念就是分析器(Analyzer)。分析器分析的過程就是將文字轉換為標記(tokens)或術語的過程,這些標記或術語被新增到倒排索引中以便進行搜尋。分析器(Analyzer)跟分詞器(Tokenizers)很像,但是它是一個比分詞器更大的一個概念,也是我們在ES裡建立對映時經常使用的一個關鍵字。例如下面的"analyzer"後面就是指定的一個ES自帶的分析器"standard":
PUT my_index { "mappings": { "_doc": { "properties": { "title": { "type": "text", "analyzer": "standard" } } } } }
分析器可以包含三個部分,字元過濾器(character filters)、分詞器(tokenizer)和分詞過濾器(token filters)。一個分析器不一定這三個部分都有,但是一般會包含分詞器。ES自帶的分析器有如下幾種:
其中Standard Analyzer是ES預設的分析器,如果你沒有指定任何分析器的話,ES將預設使用這種分析器。
分析器顧名思義就是要對ES中儲存的資料進行分析。而分析又包含兩種情況,索引時分析和查詢時分析。
- 索引時分析
例如,在對下列句子索引時,內建的english分析器將首先對其進行分析。
"The QUICK brown foxes jumped over the lazy dog!"
將這個句子轉換成不同的詞,同時將它們轉換成小寫,去掉頻繁使用的停頓詞(如the),並且減少它們的詞莖。(foxes → fox, jumped → jump, lazy → lazi),最後將下列詞語新增進倒排索引中:
[ quick, brown, fox, jump, over, lazi, dog ]
每個text型別的欄位在索引時都可以指定一個分析器
PUT my_index { "mappings": { "_doc": { "properties": { "title": { "type": "text", "analyzer": "standard" } } } } }
在索引時,如果沒有事先指定任何的分析器,那麼ES將會在索引的設定(settings)中尋找一個叫做default的分析器,如果沒有找到的話,那麼它將會預設使用standard分析器。
- 搜尋時分析
在全文查詢(如match查詢)中,搜尋時一般將同樣的分析器應用於查詢字串,以便將查詢字串中的文字轉換為與儲存在倒排索引中的文字相同的格式。
例如,使用者可能會這樣搜尋:
"a quick fox"
該句子就會被同樣的english分析器分析成下列詞語:
[ quick, fox ]
儘管查詢字串中沒有出現和 ES中儲存的一樣的字串(quick vs QUICK, fox vs foxes),但是由於二者使用同樣的分析器,所以我們同樣可以從倒排索引中查詢出我們的例項文件。所以在索引時和查詢時我們一般使用相同的分析器。像match查詢這樣的全文查詢將在對映中查詢用於每個欄位的分析器。一般通過查詢一下位置來確定用於搜尋特定欄位的分析器:
- 在查詢中指定的analyzer
- 建立對映時指定的search_analyzer引數
- 建立對映時指定的analyzer引數
- 在索引設定(settings)中的default_search中指定的分析器
- 在索引設定(settings)中的default中指定的分析器
- standard分析器
查詢的先後順序應該是從上到下依次查詢。
-
分詞器(Tokenizers)
分詞器(Tokenizers)接收一個字元流,將其分解為單個標記(通常是單個單詞),並輸出一個標記流。例如,當看到任何空白時,whitespace分詞器就會將文字分解為標記。它會將文字“Quick brown fox!”轉換為“Quick, brown, fox!” 。
分詞器(Tokenizers)還負責記錄每個詞的順序或位置(用於短語和詞接近查詢),以及該詞表示的原始詞的開頭和結尾字元偏移量(用於突出顯示搜尋片段)。
分詞器(Tokenizers)主要還是用來建立分析器(Analyzer)的。ES有很多內建的分詞器,以供使用者來自定義分析器。主要有一下幾種:
面向字的分詞器(Word Oriented Tokenizers)
部分字分詞器(Partial Word Tokenizers)
結構化文字分詞器(Structured Text Tokenizers)
利用分詞器進行字串分詞
POST _analyze { "tokenizer": "standard", "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone." }
這個句子經過分詞產生的結果如下:
[ The, 2, QUICK, Brown, Foxes, jumped, over, the, lazy, dog's, bone ]
設定分詞器的時候,可以同時進行配置。比如我們配置standard分詞器的max_token_length設定為5
PUT my_index { "settings": { "analysis": { "analyzer": { "my_analyzer": { "tokenizer": "my_tokenizer" } }, "tokenizer": { "my_tokenizer": { "type": "standard", "max_token_length": 5 } } } } } POST my_index/_analyze { "analyzer": "my_analyzer", "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone." }
分詞的結果如下,可以看到每個分詞的結果長度最大不會超過5:
[ The, 2, QUICK, Brown, Foxes, jumpe, d, over, the, lazy, dog's, bone ]
-
分詞過濾器(Token Filter)
-
字元過濾器(Character Filter)
字元過濾器用於在將字元流傳遞到分詞器之前對其進行預處理。
字元過濾器將原始文字作為字元流接收,並可以通過新增、刪除或更改字元來轉換流。舉例來說,一個字元過濾器可以用來把阿拉伯數字(٠١٢٣٤٥٦٧٨٩)轉成等價的(0123456789),或者刪除HTML標籤元素,如< b >。
Elasticsearch有許多內建的字元過濾器,可用於構建使用者自定義的分析器。如: