1. 程式人生 > >ElasticStack學習(七):ElasticSearch之Mapping初探

ElasticStack學習(七):ElasticSearch之Mapping初探

一、Mapping的概念

  1、Mapping類似於資料庫中的Schema的定義,作用如下:

    1)定義索引中的欄位的名稱;

    2)定義欄位的資料型別,例如字串、數字、日期、布林等;

    3)對每個欄位進行倒排索引的建立及相關配置;

    4)Mapping會將Json文件對映成Lucene所需要的扁平格式;

    5)一個Mapping屬於一個索引的Type,從7.0開始,不需要在Mapping中指定Type資訊;

  2、欄位的資料型別

    1)簡單型別

      Text(會增加Keyword子欄位);

      Date;

         Integer/Long/Floating;

      Boolean;

      IP4&IP6;

      Keyword;

    2)複雜型別

      物件型別;

      巢狀型別;

      陣列(由第一個非空數值的型別所決定);

      空值;

    3)特殊型別(地理資訊)

      geo_point&geo_shape

二、Dynamic Mapping的概念

  1、在寫入文件的時候,如果索引不存在,則會自動建立索引;

  2、由於上述機制,可以無需手動定義Mapping,ElasticSearch會自動根據文件資訊,推算出欄位的型別;

  3、但是有時候推算的可能不對,當型別設定的不對時,會導致一些功能無法正常執行,比如範圍內的Range查詢;

三、Mapping與Dynamic Mapping的使用

  1、推斷欄位的型別

//建立一個文件
put mapping_test/_doc/1
{
    "id":"100",
    "isvip":false,
    "isadmin":"true",
    "age":18,
    "height":180
}
//檢視索引Mapping結構
get mapping_test/_mapping
//刪除索引
delete mapping_test

   

  由上圖中可以得出,ElasticSearch基本上可以按照資料推斷出預想的欄位型別,由於isadmin欄位的值是由雙引號所括起來的,所以該欄位被推斷成text型別。

  2、更改Mapping的欄位型別

  對於索引後期加入的欄位,可以按照如下情況進行設定:

    1)新增加欄位

      a)Dynamic設定為True時,一旦有新增欄位的文件寫入,Mapping同時會被更新;

      b)Dynamic設定為False時,有新增欄位的文件寫入,Mapping不會被更新,新增欄位的資料也無法被索引,但是資訊會出現在_Source中;

      c)Dynamic設定成Strict時,文件寫入失敗;

    

    2)已有欄位

      a)對於已有欄位,一旦已經有資料寫入,就不再支援修改欄位定義。因為Lucene實現的倒排索引,一旦生成後,就不允許修改。

      b)如果希望改變已有欄位型別,必須ReIndex,重建索引;

      為什麼會這樣?

      I)如果修改了欄位的資料型別,會導致已被索引的屬於無法被搜尋;

      II)正因為如此,對於新增加的欄位,就不會有這個問題的影響;

  3、對於這幾種情況,我們通過下圖進行演示:

    1)對於dynamic為true時,對於建立的文件中的某一欄位進行搜尋,是可以查詢到的。

    

    2)將dynamic設定為false,然後新增一個name欄位,然後對其搜尋,是無法搜尋到的。

    

    同時mapping中也不存在該欄位。

    

    但是可以在_Source中看到這個欄位。

    

    3)將dynamic設定為strict,然後新增一個grade欄位,會發現出現異常。

     

 四、索引Mapping的顯式定義

  1、Mapping定義的方式有兩種:

    1)可以參考API手冊,純手寫;

    2)為了減少輸入工作量,減少出錯概率,可以依照以下步驟:

      a)建立一個臨時的Index,寫入一些樣本資料;

      b)通過訪問Mapping API獲取該臨時索引的動態Mapping定義;

      c)修改成符合要求的Json,然後建立顯式索引;

      d)將臨時索引刪除;

  2、顯式Mapping定義的語法:

Put Index_Name
{
    "mappings":{
         定義Mapping資訊,Json格式
     "properties":{
        "column_name":{
          "type":"text"
        },
        "column_name":{
          "type":"long"
        }
        ...
      }
}
}

  3、顯式Mapping定義的說明:

    1)控制當前欄位是否可以被索引,預設是True。如果設定成False,則該欄位不可被搜尋。

     將不被搜尋的欄位設定成索引為false,可以節省磁碟開銷,因為這樣該欄位就不需要進行倒排索引了。

 

    2)對於需要索引的欄位,ElasticSearch提供了Index_options配置,可以控制倒排索引記錄的內容,Index_options提供了四種控制級別:

      a)docs:記錄doc的Id;

      b)freqs:記錄doc Id、Term Frequencies;

      c)positions:記錄doc Id、Term Frequencies、Term Position;

      d)offsets:記錄doc Id、Term Frequencies、Term Position、Character offsets;

    3)Text型別預設是positions級別,其他型別預設是docs級別;

    4)索引欄位需要記錄的內容越多,那麼佔用儲存空間越大;

    5)只有keyword型別支援設定Null值;

    

    6)copy_to的設定,是將欄位的值拷貝到所設定的目標欄位中,當查詢時,可以將該目標欄位做為搜尋欄位進行查詢。但是該目標欄位不會出現在_source中。

    

     7)陣列型別在ElasticSearch中並不提供,但是對於任何欄位,是可以包含多個相同型別的資料的。

     

    8)對欄位還可以指定特定的analyzer。

    

    9)檢視索引Mapping,如下所示:  

    

五、ElasticSearch欄位特性與自定義Analyzer

  1、Exact Values(精確值)、Full Text(全文字)

    Exact Values就是指具體數字、日期、字串,此類值是不需要進行分詞的;

    Full Text:是非結構化的文字資料,是需要進行分詞的;

  

  2、自定義分詞器

  當ElasticSearch自帶的分詞器無法滿足要求時,可以自定義分詞器,通過組合不同的Character Filter、Tokenizer、Token Filter進行實現。

  1)Charater Filters

    a)在Tokenizer之前,通過使用Character Filters對文字進行處理,如刪除或者替換字元。此種處理會影響後續Tokenizer對Term的Position與Offset的資訊。

    b)可以設定多個Character Filters,一個自帶的Character Filters包括:HTML Strip(去除HTML標籤)、Mapping(字串替換)、Pattern Replace(正則表示式替換)。

    如下圖所示:

    

    

    

  2)Tokenizer

    a)將原始的文字按照一定的規則,進行切分成詞(Term or Token);

    b)內建的Tokenizer有:Standard、uax_url_email、WhiteSpace、keyword、Pattern、Path hierarchy;

    c)可以實現自己的Tokenizer外掛;

    如下圖所示:

    

   3)Token Filters

    a)將Tokenizer輸出的Term,進行增加、修改、刪除;

    b)內建的Token Filters有:lowercase、stop、synonym(近義詞);

    如下圖所示:

    

  3、自定義Analyzer使用

   

  在圖中的emotion、customer、english_stop,是分別對Character Filter、Tokenizer、Token Filter的自定義配置。

   

  注意:欄位型別keyword與text型別的子欄位keyword的說明:

    1、一切文字型別的字串可以定義成"text"或"keyword"兩種型別。區別在於,text型別會使用預設分詞器分詞(當然也可以指定特定的分詞器),keyword型別預設不會對其進行分詞;

    2、多欄位型別情況下,查詢時可以用title,也可以用title.keyword查詢型別為keyword的子欄位;

 

  大家可關注我的公眾號 

    

  知識學習來源:阮一鳴:《Elasticsearch核心技術與實戰》