- Elastic Stack應用寶典
- 田雪松編著
- 2261字
- 2020-07-22 17:21:30
4.4 分析器與規整器
在Elasticsearch中,文檔編入索引時會從全文數據中提取詞項,這個過程被稱為文檔分析(Analysis)。文檔分析不僅存在于文檔索引時,也存在于文檔檢索時。文檔分析會從查詢條件的全文數據中提取詞項,然后再根據這些詞項檢索文檔。文檔分析器(Analyzer)是Elasticsearch中用于文檔分析的組件,通常由字符過濾器(Character Filter)、分詞器(Tokenizer)和分詞過濾器(Token Filter)三部分組成。它們就像是連接在一起的管道,共同完成對全文數據的詞項提取工作。如圖4-1所示。

圖4-1 文檔分析器
字符過濾器讀入最原始的全文數據,并對全文數據中的字符做預處理,比如從HTML文檔中將類似<b>這樣的標簽刪除。字符過濾器可以根據實際情況添加,可以沒有也可以有多個。分詞器接收由字符過濾器處理完的全文數據,然后將它們根據一定的規則拆分成詞項。英文分詞規則比較簡單,直接使用空格分隔單詞即可;但中文分詞規則比較復雜,需要根據詞意做分詞且需要字典支持。對于一個分析器來說,分詞器是必不可少的,而且只能有一個。在使用分析器時,可以根據文檔內容更換分詞器,比如對于中文來說需要將分析器的分詞器更換為中文分詞器。最后,分詞過濾器的職責是接收由分詞器提取出來的所有詞項,然后對這些分詞做規范化處理,比如將分詞轉換為小寫、去除“的、地、得”等停止詞(Stop Word)。分詞過濾器與字符過濾器一樣,可以根據需要添加和配置,可以沒有也可以有多個。
除了分析器以外,Elasticsearch還提供了一種稱為規整器(Normalizer)的文檔標準化工具。規整器與分析器的最大區別在于規整器沒有分詞器,而只有字符過濾器和分詞過濾器,所以它能保證分析后的結果只有一個分詞。文檔規整器只能應用于字段類型為keyword的字段,可通過字段的normalizer參數配置字段規整器。規整器的作用就是對keyword字段做標準化處理,比如將字段值轉為小寫字母等等。規整器與分析器共享相同的字符過濾器和詞項過濾器,但規整器只能使用那些結果只有一個詞項的過濾器。
4.4.1 設置分析器
由于文檔分析通過分析器完成詞項提取,所以想要影響文檔索引和文檔檢索時的詞項提取,就要修改它們使用的分析器。對于所有text類型的字段,都可以在創建索引時為它們指定分析器。對于非text類型字段來說,由于本身不存在全文本數據詞項提取的問題,所以也就沒有設置分析器的問題。例如,在示例4-20中,title字段在文檔編入索引時使用standard分析器,而通過title字段檢索文檔時則使用simple分析器:

示例4-20 設置分析器
在創建索引時如果沒有指定分析器,Elasticsearch會查找名為default的分析器,如果沒有則使用standard分析器。文檔檢索時使用的分析器有一點復雜,它依次從如下參數中查找文檔分析器,如果都沒有設置則使用standard分析器:
1)檢索請求的analyzer參數;
2)索引映射字段的search_analyzer參數;
3)索引映射字段的analyzer參數;
4)索引配置中的default_search參數。
以示例4-20中的articles索引為例,盡管設置的檢索分析器為simple,但如果在檢索文檔時使用analyzer參數設置為english分析器,最終使用的分析器依然是english分析器。如第4.1節所述,analyzer參數可以作為_search接口的URI參數也可以出現的請求體中,例如:

示例4-21 analyzer參數
4.4.2 _analyze接口
Elasticsearch提供了一個_analyze接口,可以用于查看分析器處理結果,這在學習分析器時非常有幫助。由于_analyze接口僅用于查看分析器功能,所以在發送請求時不需要指定索引,雖然在指定索引時也不會報錯。例如示例4-22就是用standard分析器處理文本:

示例4-22 _analyze接口
_analyze接口可以使用POST發送請求,也可以使用GET發送請求。返回的結果中,將包含所有提取出來的詞項以及它們的位置、偏移量等信息:

示例4-23 _analyze接口返回結果
其中,token是提取出來的詞項,start_offset與end_offset是詞項在整個文本中的起始位置和終止位置(即偏移量),position是詞項在所有詞項中的次序,而type則是詞項的類型(與詞項本身和分析器相關)。如果要查看分詞中更詳細的內容,可以在請求體中將explain參數設置為true。
實際上除了analyzer參數以外,還可以使用tokenizer、filter、char_filter的組合來測試分詞器、分詞過濾器、字符過濾器的功能。
4.4.3 _termvectors接口
_termvectors接口提供了實時查看一段文本提取詞項結果的功能,可以使用POST或GET方法請求該接口。該接口查看詞項結果時所使用的文本內容可以來自索引中某一文檔的字段內容,也可以是在調用接口時動態指定一段文本。所以該接口有兩種請求方式,并且它們不能同時使用,只能任選其一。第一種方式是在請求路徑中指定文檔_id,并在路徑或請求體中通過設置fields參數指定要查看的字段名稱。例如:

示例4-24 _termvectors接口fields參數
在示例4-24中,請求路徑中的索引名稱和文檔ID(_termvectors后面的值)都必須要指定。在示例中文檔ID由于太長,所以做了一些節略。兩個請求都是通過fields參數指定要查看詞項的字段名稱,可以指定一個也可以指定多個。第二種方式與此不同,它要求路徑中一定不能包含文檔_id,而是在請求體中通過doc參數指定文本內容。例如:

示例4-25 _termvectors接口doc參數
在示例4-25中,doc參數指定了兩個字段message和agent,Elasticsearch會分別返回這兩個字段詞項的提取情況。doc參數指定的字段必須是索引中已經存在的字段,該接口會忽略索引中不存在的字段。通過這種方式也能看出來,這個接口是實時做詞項分析。即使是使用第一種方式指定到具體的文檔字段上,它也不是直接去讀取已經提取的詞項,而是使用索引或字段設置的分析器實時提取詞項。_termvectors接口返回的結果中主要包含field_statistics和terms兩個字段,它們分別給出提取詞項的統計數據和詳細信息,這些對于分析檢索時出現的問題將會十分有用。
除此之外,Elasticsearch還提供了_mtermvectors接口,可以一次查詢多個文檔的詞項信息。這些文檔甚至可以分散在不同的索引和映射類型中,例如:


示例4-26 _mtermvectors接口
在示例4-26中,_mtermvectors接口的路徑中并沒有包含索引和文檔ID,它們是通過在請求體中添加docs數組,并設置數組每個元素的_index和_id參數指定。如果要查詢的詞項信息在同一個索引中,則可以在_mtermvectors前面添加索引名稱,而無須在docs數組中再設置對象的_index參數。
- Beginning C++ Game Programming
- Ext JS Data-driven Application Design
- Java 11 Cookbook
- jQuery開發基礎教程
- 小程序開發原理與實戰
- Swift語言實戰精講
- Java編程的邏輯
- Quantum Computing and Blockchain in Business
- HTML5開發精要與實例詳解
- Learning Node.js for .NET Developers
- Scala編程(第5版)
- 自學Python:編程基礎、科學計算及數據分析(第2版)
- Mastering Adobe Captivate 7
- 零基礎C#學習筆記
- Python網絡爬蟲實例教程(視頻講解版)