ElasticSearch中的映射

         這裏講的ElasticSearch中的映射(schema mapping),是定義存儲和索引的文檔類型和字段的過程。這裏記住映射是一個動態過程。索引中的每個文檔都有一個類型,每種類型都有他本身的映射。映射起到定義文檔字段的數據類型的功能,這一功能實際上是經過配置來定義字段類型和該類型關聯的元數據的關係來實現的。json

映射類型

每一個索引都有一個或多個映射類型,他的做用是在一個索引中將數據劃分爲不一樣的邏輯組。每一個映射類型都由元字段和字段組成。數組

1.元字段

元字段的做用是用來表示如何處理文檔的元數據。常見的元字段有 _index,_type,_id,_source。 每一個文檔都有與之關聯的元數據,元字段是保證系統正常運轉的內置字段。app

2.字段(或屬性)

字段(或屬性)的做用是標識數據的類型。每一個映射類型都包含與類型相關的字段或者屬性列表。這裏注意若是是在同一個索引中的不一樣映射類型的相同字段都具備相同的數據類型,意思是指在同一索引範圍中,只要映射字段相同,那麼他就具備相同的映射類型。編碼

字段數據類型

ElasticSearch中的字段數據類型包括基本的字符串,日期,長整型long,雙精度double,布爾型boolean,相似JSON的對象,IP,地理點和地理形狀(之後會對不一樣的類型作詳細解釋)。ElasticSearch能夠顯式或者動態的設置映射,ElasticSearch的映射能夠不事先定義,依靠動態映射,依靠新的索引文檔,新的類型和字段名能夠自動添加。而新的類型映射又能夠添加到頂級映射類型或者映射類型內部的對象和嵌入字段。url

映射類型在一個索引中是惟一的。也就是在同一個索引的不一樣類型中,相同的映射名稱同樣,那麼他們就具備相同的類型。3d

1. 核心數據類型

  • 字符串數據類型

字符串數據類型能夠分爲全文本和關鍵詞,同一字段又能夠同時設置全文本和關鍵字。全文本很是適合基於文本的相關性搜索。rest

全文本的字符串數據類型能夠分詞,在索引執行以前經過分詞器將文本轉化爲單詞表,這個操做就是ElasticSearch能在全文本中搜索單詞的原理。這裏注意全文本的字符串數據類型不用於排序且不多用於聚合。code

關鍵詞的字符串數據類型一般用來過濾,排序和聚合。而且不參與分詞。cdn

  • 數字
  • 日期類型:注意json沒有日期類型,因此只能是字符串,表明時間毫秒數的長整型,或者整型。可使用雙豎線作多日期格式匹配。
  • boolean類型
  • base64編碼的二進制值。不以默認方式存儲且不能被搜索。

2. 複雜數據類型

  • 數組

ElasticSearch沒有特定的數組類型,可是每一個字段默承認以包含一個或者多個相同數據類型的值。對象

  • 對象類型

這裏指的對象類型採用的是json的自然分層特性。json文檔內部能夠包含對象。

  • 嵌套數據類型

3. 地理數據類型

這裏的地理數據類型說的是經緯度。從經緯度擴展一下幾個方面:

  • 查找必定地理範圍內的數據
  • 聚合距離中心點必定距離的文檔
  • 按照距離中心點的遠近進行排序
  • 整合地理數據到文檔的相關性評分中

地理數據類型又分爲:

  • 地理點
  • 地理形狀

3. 專門數據類型

  • IP
  • 單詞計數器:token_count

映射參數

用於字段映射的參數。ElasticSearch中有大量的映射參數,這些參數的默認值都是最合適廣泛場景的,可是若是想精通調優,須要理解這些映射參數。下面這些是選取的幾個典型映射參數。

1.analyzer

字符串在索引和查詢時,都是被分析爲一個個索引詞。經過合理的配置索引器能夠大大提升在索引查詢時的效率。

2.boost

對字段進行加權。默認值爲1,若是設置了值則是所設置值的倍數。這裏注意在數據索引時最好不要加權。由於除非從新索引全部文檔,否則加權值不會變。

3.coerce

強制類型轉換。若是值爲false,在索引到不匹配類型的文檔時就會丟棄

4.facat

facat表明多字段,ElasticSearch容許你在一個字段上設定兩種類型。假如你想在同一個字段上進行兩種分析,一種用於搜索,一種用於排序。或一個通過特定語言分析器來分析,而另外一個只通過空白字符分析。那麼可使用多字段功能。該功能能夠容許用戶只定義一個字段類型就同時賦予該字段兩種類型的類型。以下所示:

「name」:{ 「type」:」string」, 「property」:{ 「facat」:{「type」:」string」,」index」:」not_anayzed"} } }

這樣就定義了兩個字段,一個叫name,一個叫name.property,ElasticSearch會把name字段中的值複製到name.property字段中。

5.copy_to

ElasticSearch可使用這個字段來建立自定義的_all字段。也就是說能夠用多個字段來合成一個字段,把這個合成的字段當作單個字段來查詢。

6.doc_valus

倒排索引的列式存儲。這種結構很適合聚合,排序,腳本操做。

動態索引

ElasticSearch能夠在事先不設置索引結構的狀況下,在文檔直接插入到索引中時,系統會根據文檔自動進行索引結構的動態映射。這樣作極大地簡化了索引的操做。

能夠根據目的來指定動態映射生成的規則:

  • ElasticSearch中有個名爲_default_的默認映射,這個默認映射至關於建立新映射類型的基礎映射。
  • 動態字段映射。
  • 動態模板:也就是根據事先定義好的自定義規則來配置動態添加字段的映射。

默認狀況下,在文檔中發現新的字段的時候,ElasticSearch會自動根據一系列簡單的規則將新字段添加到類型映射中。這些簡單的規則中,有些能解析形如日期的字符串,有些能解析數字。其實ElasticSearch底層是經過定義文檔的JSON來猜想文檔結構和數據類型的,好比字符串是被引號包圍,布爾值使用特定的字符,數值則是一些數字類型。很明顯,這些簡單的規則有效並且易於理解。

那麼有沒有更加靈活的文檔類型探測呢?好比被引號包圍的數字類型能不能被檢測爲數值類型呢,答案是確定的。ELasticsearch有種機制叫數值自動檢測,相關聯的設置爲numeric_detection,該選項是默認關閉的,可使用響應的put請求來打開該選項。若是該選項打開後,在索引數據時若是被引號包圍的數據爲數組類型,好比float型數據,那麼在索引完後,使用get方法來請求索引的_mapping_數據,你會發現剛纔的數值類型的字段的type爲double了,固然若是索引的數值不是float,而是long類型數據,那麼_mapping中的類型也會變成long。

映射是如何xxx的

首先找到映射的入口。因爲都是從rest的接口新增的映射,因此從rest包中入手確定沒有錯。因爲rest包中的類很少,查看後知道了映射相關的類在indices包中。由於在映射都是依附在index上的,因此放到了indices包下。以下圖所示:

新增映射的入口

接下來找到入口,就分析是如何構造映射的。

  • 首先經過url中的index字段構造一個初始的PutMappingRequest
  • 而後給該PutMappingRequest構造各類request中攜帶的參數
    • type:映射相關元數據
    • source:映射相關元數據
    • update_all_types:是否跨多個類型的映射字段都更新
    • timeout:超時
    • master_timeout:若是在沒有發現master或者斷開與master鏈接狀況下的超時值
    • expand_wildcards:索引配置相關,啓用的擴展通配符
    • ignore_unavailable:索引配置相關,snapshot,restore和index_settings操做使用此設置。
    • allow_no_indices:索引配置相關,
  • 最後經過NodeClient(實現了IndicesAdminClient接口)中的putMapping方法,將上一步構造好的action傳給ElasticSearch的client。

下圖顯示了實際執行映射操做的地方是NodeClientexecute方法

d

上面提到的PutMappingRequest初始化的參數以下圖所示,可看到咱們put的數據都在source中:

而後會從actions中找到putmapping的action,action的類型爲TransportAction。而該action的實際執行方法execute,該方法是當transport操做調用致使產生一個新的關聯任務時,實際使用的方法。

咱們能夠看到該方法使用默認好的actionName'indices:admin/mapping/put'和構造好的putMappingRequest註冊了一個task。而後分別在ActionListener中設置了成功和失敗的回調方法。

因爲我是單節點運行的ElasticSearch,因此在實際執行任務的類是TransportMasterNodeAction,這個類是須要在主節點上執行的操做的基類。在該類的doStart方法中,經過類TransportPutMappingAction和參數taskreqeust最衆到達實際的方法metaDataMappingService.putMapping中,以下圖所示;

至此前面的任務調度工做就都作完了,之後就是metaDataMappingService.PutMappingExecutor的工做了。

相關文章
相關標籤/搜索