Elasticsearch學習筆記(七)—Elasticsearch分析器與映射

一、確切值(Exact values) vs 全文文本(Full text)

Elasticsearch中的數據可以大致分爲兩種類型

  • 確切值,確切值是確定的,正如它的名字一樣。比如一個date或用戶ID,需要精確匹配,對於2019-11-8,只輸入2019-11是不能被檢索出來,必須精確匹配
  • 全文文本,Elasticsearch會對文本分析(analyzes),然後使用結果建立一個倒排索引,比如,可以支持模糊匹配,忽略大小寫,近義詞匹配

二、Elasticsearch分析器

分析器需要完成以下分析過程:

  • 表徵化一個文本塊爲適用於倒排索引單獨的詞(term)
  • 然後標準化這些詞爲標準形式,提高他們的“可搜索性”

ES分析器組成:

  • 字符過濾器
    首先字符串經過過濾器(character filter),他們的工作是在表徵化前處理字符串。字符過濾器能夠去除HTML標記,或者轉化爲“&”爲“and”
  • 分詞器( Tokenizers ) 可以根據空格或逗號將單詞分開
    分詞器(tokenizer)被表徵化爲獨立的詞。一個簡單的分詞器(tokenizer)可以根據空格或逗號將單詞分開(注:這個在中文中不適用)
  • 標記過濾器 ( token filters )
    每個詞都通過所有表徵過濾(token filters),可以修改詞(例如將“Quick”轉爲小寫),去掉詞(例如停用詞像“a”、“and”、“the”等等),或者增加詞(例如同義詞像“a”、“and”、“the”等等)或者增加詞(例如同義詞像“jump”和“leap”)

內置分析器

  • 標準分析器,Elasticsearch默認使用的分析器,它是分析各種語言文本最常用的選擇,根據 Unicode 聯盟 定義的 單詞邊界 劃分文本。刪除絕大部分標點。最後,將詞條小寫
  • 簡單分析器,在任何不是字母的地方分隔文本,將詞條小寫
  • 空格分析器,在空格的地方劃分文本
  • 語言分析器,可以考慮指定語言的特點

什麼時候使用分析器?
當我們索引一個文檔,它的全文域被分析成詞條以用來創建倒排索引。 但是,當我們在全文域搜索 的時候,我們需要將查詢字符串通過 相同的分析過程 ,以保證我們搜索的詞條格式與索引中的詞條格式一致

  • 當你查詢一個全文域時, 會對查詢字符串應用相同的分析器,以產生正確的搜索詞條列表。
  • 當你查詢一個精確值域時,不會分析查詢字符串,而是搜索你指定的精確值

三、映射介紹

數據庫中的表,我們一般在DDL語句中爲每個字段指定存儲類型,例如:varchar,int,datetime等等,目的很明確,就是更精確的存儲數據,防止數據類型格式混亂

類比數據庫,ES的索引字段也需要爲其指定類型,它就像數據庫中的 schema,這種在ES稱爲映射(mapping)

映射是定義一個文檔及其包含的字段如何存儲和索引的過程,可以從以下幾個方面理解:

  • 將哪些字符串字段視爲全文字段
  • 哪些字段包含數字,日期或地理位置
  • 日期值的格式
  • 自定義規則以控制動態添加字段的映射

動態映射: 文檔寫入es時,es可根據寫入內容的類型自動識別,生成mapping
靜態映射: 手動爲索引指定字段類型

四、字段類型

JSON格式的數據 自動推測字段類型
null 沒有字段被添加
true or false boolean
浮點類型數字 float類型
數字 long類型
JSON對象 object類型
數組 由數組中第一個非空值決定
string 有可能是date類型(開啓日期檢測)、double或long類型、text類型、keyword類型

text 和 keyword 的區別:

  • text 用於索引全文值的字段,例如電子郵件正文或產品說明。這些字段是analyzed,它們通過分詞器傳遞 ,以在被索引之前將字符串轉換爲單個術語的列表。分析過程允許Elasticsearch搜索單個單詞中 每個完整的文本字段。文本字段不用於排序,很少用於聚合
  • keyword 用於索引結構化內容的字段,例如電子郵件地址,主機名,狀態代碼,郵政編碼或標籤。它們通常用於過濾,排序,和聚合。keyword字段只能按其確切值進行搜索。如果您需要索引電子郵件正文或產品說明等全文內容,則可能應該使用text字段

有時候單純的一個字段類型滿足不了我們複雜的需求,爲了不同的目的,以不同的方式索引同一個字段通常很有用,例如,對於字符串字段,我們既可以將它映射爲text類型用於全文搜索,亦可以將它映射爲keyword類型用於排序或聚合,或者,還可以使用標準分詞器、英語分詞器和其他語言分詞器索引文本字段

前面說過,當 Elasticsearch 遇到文檔中以前 未遇到的字段,它用 dynamic mapping 來確定字段的數據類型並自動把新的字段添加到類型映射。

如果不希望這樣,可以使用dynamic參數設置

  • true,動態添加新的字段
  • false,忽略新的字段
  • strict,如果遇到新字段拋出異常

配置參數 dynamic 可以用在根 object 或任何 object 類型的字段上。你可以將 dynamic 的默認值設置爲 strict , 而只在指定的內部對象中開啓它, 例如:

PUT /my_index
{
    "mappings": {
        "my_type": {
            "dynamic":      "strict", 
            "properties": {
                "title":  { "type": "string"},
                "stash":  {
                    "type":     "object",
                    "dynamic":  true 
                }
            }
        }
    }
}
  • 如果遇到新字段,對象 my_type 就會拋出異常
  • 內部對象 stash 遇到新字段就會動態創建新字段

參考

Elasticsearch權威指南

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章