乾貨 | Elasticsearch基礎但非常有用的功能之二:模板
- 2019 年 12 月 4 日
- 筆記
1、 引言
業務場景1:數據量非常大,需要進行索引生命周期管理,按日期劃分索引,要求多個索引的Mapping一致,每次手動創建或者腳本創建都很麻煩! 怎麼破?
業務場景2:實際業務多個索引,想讓多個索引中的相同名字的欄位類型完全一致,以便實現跨索引檢索。怎麼破?

思考上面兩個問題,當單Mapping不能解決多索引問題時,模板的作用就體現出來了。
下文中:模板=template,映射=Mapping。
2、Elasticsearch模板是什麼鬼?
【維基百科】模板:或稱樣板、範本,通常指具有固定內容、可構建多個不同實例的可重用樣板。
Elasticsearch索引template指:在創建新索引時將自動套用的模板。
直接上樣例,一探究竟。
1 PUT _template/template_1 2{ 3 "index_patterns": ["te*", "bar*"], 4 "aliases" : { 5 "alias1" : {}} 6 "settings": { 7 "number_of_shards": 1 8 }, 9 "mappings": { 10 "_source": { 11 "enabled": false 12 }, 13 "properties": { 14 "host_name": { 15 "type": "keyword" 16 }, 17 "created_at": { 18 "type": "date", 19 "format": "EEE MMM dd HH:mm:ss Z yyyy" 20 } 21 } 22 } 23}
其中: index_patterns代表匹配的索引。 settings 指索引層面的設置。 可以設置索引層面的配置,包括:
- 分片數(number_of_shards)、
- 副本數(number_of_replicas)、
- 刷新頻率(refresh_interval)
…..
mappings:欄位映射。
aliases:指定索引的別名。
別名的妙處參考:Elasticsearch基礎但非常有用的功能之一:別名
3、Elasticsearch模板的基礎操作
3.1 增
1PUT _template/template_1 2...
如第二節的示例。
3.2 刪
1DELETE /_template/template_1
3.3 改
直接執行3.1的創建模板操作,會生成相同名稱的新的模板,並會覆蓋掉原來創建的模板。
新模板只對新創建的索引生效,對歷史索引不起作用。
3.4 查
1GET /_template/template_1
4、Elasticsearch模板進階實戰
當template和Mapping的dynamic_templates結合就相當於放了大招
。
直接拿個實戰例子說明問題。
需求1:默認如果不顯示指定Mapping,數值類型的值會被映射會long類型,但實際業務數值都比較小,會有存儲浪費。需要將默認值改成integer。
需求2:date_*開頭的字元統一匹配為date日期類型。
實戰如下:
1PUT sampleindex/_doc/1 2{ 3 "Value":123 4} 5 6GET sampleindex/_mapping 7 8 9PUT _template/sample_dynamic_template 10{ 11 "index_patterns": [ 12 "sample*" 13 ], 14 "mappings": { 15 "dynamic_templates": [ 16 { 17 "handle_integers": { 18 "match_mapping_type": "long", 19 "mapping": { 20 "type": "integer" 21 } 22 } 23 }, 24 { 25 "handle_date": { 26 "match": "date_*", 27 "unmatch": "*_text", 28 "mapping": { 29 "type": "date" 30 } 31 } 32 } 33 ] 34 } 35} 36 37DELETE sampleindex 38PUT sampleindex/_doc/1 39{ 40 "Value":123, 41 "date_curtime":"1574494620000" 42} 43 44GET sampleindex/_mapping
- index_patterns:對應待匹配的以」sample開頭的「索引。
- handle_integers:動態模板的名字,你可以自己定義。
- match_mapping_type:被匹配的被重寫的源數據類型。
- match/unmatch:匹配欄位類型。
整個操作的核心是:將默認的long改成integer,date_*開頭匹配為date類型。
更多分類如下:

核心參見:
https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-templates.html
不再贅述。
5、常見問題
問題1:template和Mapping到底什麼區別?
- Mapping: 針對單一索引。 類似Mysql中的表結構定義,是所有數據存儲到該索引的架構定義。 欄位支援:1)靜態明確定義、2)系統層面自動識別、3)動態匹配。
- template: 針對一個或多個索引。 除了定義Mapping的全支援外,還可以指定Setting、別名等。 適合數據量大、靈活多變的業務場景。
問題2:模板里可以指定Mapping,那我們還需要Mapping做什麼?
- 索引模板對於在多個索引創建映射時非常有用。
- 如果數據量少,業務場景單一,那隻Mapping也能解決問題。
問題3:如果我想更新Mapping,更新模板可以嗎?
認知前提:Mapping一旦創建了,不能修改。除非進行reindex操作。
- 一旦創建了索引,對索引模板的更新將不會影響該索引。更新模板僅適用於新索引。
- 同樣,更新為dynamic_templates僅會影響索引中的新欄位。
問題4:模板order起到什麼作用?
拿星球同學實戰例子舉例一下:
問題:我現在想創建2個template,其中模板B-template有副本設置,另外一個A-template沒有副本設置,我可以這樣配置嗎?
- 其中B-template匹配到我單獨設置的幾個索引("logstash-B-tomcat-","logstash-B1-tomcat-","logstash-B2-server-*","logstash-B3-tomcat"),
- 另外A-template匹配所有,我設置B-template的order比A-template高,是不是我那4個索引就會匹配到B-template呢?
正確寫法參考:
1PUT _template/b-template 2{ 3 "order":1, 4 "index_patterns":["logstash-b-tomcat-*","logstash-b1-tomcat-*","logstash-b2-server-*","logstash-b3-tomcat-*"], 5 "settings":{ 6 "number_of_shards":"5", 7 "number_of_replicas":"1", 8 "refresh_interval":"30s", 9 "translog.durability":"async" 10 } 11} 12 13PUT logstash-b-tomcat-1 14 15PUT _template/a-template 16{ 17 "order":0, 18 "index_patterns":["*"], 19 "settings":{ 20 "number_of_shards":"5", 21 "number_of_replicas":"0", 22 "refresh_interval":"30s", 23 "translog.durability":"async" 24 } 25}
核心原理:order高會覆蓋order低的模板。
6、小結
實戰中,你會發現:template是高效的的工具,可全局設置多個索引且批量生效,避免的不必要的返工。 相比之下Mapping和別名優勢如下:
- Mapping有助於我們保持資料庫結構的一致性,並為我們提供Elasticsearch豐富的數據類型以及更複雜的自定義Mapping和分析類型。
- 別名Alias對於最大限度地無需停服完成索引切換起到重要作用。
因此,當我們新系統準備選型Elasticsearch作為核心數據存儲時,優先注意數據建模;數據建模的過程中要整合template、alias和mapping的綜合優勢,才能保證模型的健壯性。