索引模板责嚷,簡而言之罕拂,是一種復(fù)用機制爆班,就像一些項目的開發(fā)框架一樣蛋济,省去了大量的重復(fù),體力勞動祟辟。當(dāng)新建一個 Elasticsearch 索引時旧困,自動匹配模板吼具,完成索引的基礎(chǔ)部分搭建拗盒。
典型的如下所示:
{
"order": 0,
"template": "sample_info*",
"settings": {
"index": {
"number_of_shards": "64",
"number_of_replicas": "1"
}
},
"mappings": {
"info": {
"dynamic_templates": [
{
"string_fields": {
"mapping": {
"analyzer": "only_words_analyzer",
"index": "analyzed",
"type": "string",
"fields": {
"raw": {
"ignore_above": 512,
"index": "not_analyzed",
"type": "string"
}
}
},
"match_mapping_type": "string",
"match": "*"
}
}
]陡蝇,
"properties": {
"user_province": {
"analyzer": "lowercase_analyzer",
"index": "analyzed",
"type": "string",
"fields": {
"raw": {
"ignore_above": 512,
"index": "not_analyzed",
"type": "string"
}
}
}
}
}
},
"aliases": {}
}
上述模板定義广匙,看似復(fù)雜鸦致,拆分來看蹋凝,主要為如下幾個部分:
{
"order": 0, // 模板優(yōu)先級
"template": "sample_info*", // 模板匹配的名稱方式
"settings": {...}, // 索引設(shè)置
"mappings": {...}, // 索引中各字段的映射定義
"aliases": {...} // 索引的別名
}
1、模板參數(shù)
1.1 模板優(yōu)先級
有時候迄汛,一個模板可能絕大部分符合新建索引的需求鞍爱,但是局部需要微調(diào),此時沉填,如果復(fù)制舊的模板,修改該模板后佑笋,成為一個新的索引模板即可達到我們的需求翼闹,但是這操作略顯重復(fù)。此時蒋纬,可以采用模板疊加與覆蓋來操作猎荠。模板的優(yōu)先級是通過模板中的 order 字段定義的,數(shù)字越大蜀备,優(yōu)先級越高关摇。
如下為定義所有以 te 開頭的索引的模板:
{
"order": 0
"template" : "te*",
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"type1" : {
"_source" : { "enabled" : false }
}
}
}
索引模板是有序合并的。如何想單獨修改某一小類索引的一兩處單獨設(shè)置碾阁,可以在累加一層模板。
{
"order" : 1,
"template" : "tete*",
"settings" : {
"number_of_shards" : 2
},
"mappings" : {
"type1" : {
"_all" : { "enabled" : false }
}
}
}
上述第一個模板的 order 為0艰猬,第二個模板的 order 為1,優(yōu)先級高于第一個模板胸蛛,其會覆蓋第一個模板中的相同項。所以對于所有以 tete 開頭的索引模板效果如下:
{
"settings" : {
"number_of_shards" : 2
},
"mappings" : {
"type1" : {
"_source" : { "enabled" : false },
"_all" : { "enabled" : false }
}
}
}
兩個模板疊加了,項目的字段,優(yōu)先級高的覆蓋了優(yōu)先級低的,如分片數(shù)。
1.2 索引模板的匹配
索引模板中的 "template" 字段定義的是該索引模板所應(yīng)用的索引情況。如 "template": "tete*" 所表示的含義是,當(dāng)新建索引時,所有以 tete 開頭的索引都會自動匹配到該索引模板后室。利用該模板進行相應(yīng)的設(shè)置和字段添加等贡避。
1.3 setting 部分
索引模板中的 setting 部分一般定義的是索引的主分片杀捻、拷貝分片拄踪、刷新時間、自定義分析器等。常見的 setting 部分結(jié)構(gòu)如下:
"settings": {
"index": {
"analysis": {...}, // 自定義的分析器
"number_of_shards": "32", // 主分片的個數(shù)
"number_of_replicas": "1", // 主分片的拷貝分片個數(shù)
"refresh_interval": "5s" // 刷新時間
}
}
建立的索引肠槽,不會立馬查到寂纪,這是為什么 Elasticsearch 為 near-real-time(接近實時)的原因迈倍,需要配置刷新時間,默認(rèn)的是 1s。setting 的設(shè)置中,重點是自定義分析器的設(shè)置。
分析器是三個順序執(zhí)行的組件的結(jié)合夜畴。他們分別是字符過濾器均函、分詞器墩朦、標(biāo)記過濾器引润。
- 字符過濾器是讓字符串在被分詞前變得更加整潔。一個分析器可能包含零到多個字符過濾器(character_filter)蠢古。
- 分詞器將字符串分割成單獨的詞(terms)或標(biāo)記(tokens)洽糟。一個分析器必須包含一個分詞器薪介。
- 分詞器分詞的結(jié)果的標(biāo)記流會根據(jù)各自的情況烂完,傳遞給特定的標(biāo)記過濾器嘶窄。標(biāo)記過濾器可能修改、添加或刪除標(biāo)記。
創(chuàng)建的創(chuàng)建自定義分析器結(jié)構(gòu)如下:
"settings": {
"index": {
"analysis": {
"char_filter": { ... }, // 用戶自定義字符過濾器
"tokenizer": { ... }, // 用戶自定義分詞器
"filter": { ... }, // 用戶自定義標(biāo)記過濾器
"analyzer": { ... } // 用戶自定義分析器
},
...
}
}
1.3.1 字符過濾器
目前字符過濾器共分為三種:映射字符過濾器(mapping char filter)、HTML過濾器(HTML Strip char filter)失球、格式替換過濾器(Pattern Replace char filter)岖是。html_strip 字符過濾器去除所有的 HTML 標(biāo)簽。
如下定義一個 mapping 字符過去器实苞。將 & 替換成 and豺撑。
"char_filter": {
"&_to_and": {
"type": "mapping",
"mappings": [ "&=> and "]
}
}
mapping 字符過濾器的格式如上,其中 type 字段定義該字符過濾器的類型是 mapping 黔牵。其中 mappings 對應(yīng)的數(shù)組為索要替換的字段聪轿。
如下在定義一個格式替換過濾器(Pattern Replace Char Filter),將點 "." 替換成空格猾浦。
"char_filter": {
"replace_dot": {
"pattern": "\\.",
"type": "pattern_replace",
"replacement": " "
}
}
格式替換過濾器的格式如上陆错、必須包含 "pattern"、"type"金赦、"replacement" 三個字段音瓷。其中 pattern 定義的是滿足替換的格式,type 則定義為格式替換類型夹抗。replacement 則是對于滿足格式的字符串绳慎,要替換成的字符串。
1.3.2 分詞器
常用的分詞器有 standard、keyword偷线、whitespace磨确、pattern等。
standard 分詞器將字符串分割成單獨的字詞声邦,刪除大部分標(biāo)點符號乏奥。keyword 分詞器輸出和它接收到的相同的字符串,不做任何分詞處理亥曹。whitespace 分詞器只通過空格倆分割文本邓了。pattern 分詞器可以通過正則表達式來分割文本。最常用的一般為 standard 分詞器媳瞪。
更多的分詞器詳見官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/analysis-standard-tokenizer.html
1.3.3 標(biāo)記過濾器
常用的標(biāo)記過濾器有 lowercase 和 stop 骗炉。lowercase 標(biāo)記過濾器將詞轉(zhuǎn)換為小寫,stop 標(biāo)記過濾器用戶去除一些自定義停用詞或者是語言內(nèi)定義的停用詞蛇受。
stop 標(biāo)記過濾器的常用結(jié)構(gòu)如下:
"filter": {
"my_stopwords": {
"type": "stop",
"stopwords": [ "the", "a" ]
}
}
上述標(biāo)記過濾器是自定義的過濾掉 "the" 句葵、"a" 兩詞。除了自定義兢仰,還有特定的語言停用詞過濾乍丈,相應(yīng)的有:spanish 、english等把将。具體用法如下:
"filter": {
"my_stop": {
"type": "stop",
"stopwords": _spanish_
}
}
更多的語言停用詞參考官方網(wǎng)址:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/analysis-stop-tokenfilter.html/
1.3.4 分析器組合
如上定義了字符過濾器轻专、分詞器、標(biāo)記過濾器之后察蹲,就該用戶自定義分析器请垛。分析器是由三者按順序組合而成。
將上述組件組合起來便是:
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": [ "html_strip", "&_to_and", "replace_dot" ],
"tokenizer": "standard",
"filter": [ "lowercase", "my_stopwords", "my_stop" ]
}
}
將自定義分析器各部分完整表示如下:
"settings": {
"index": {
"analysis": {
"char_filter": {
"&_to_and": {
"type": "mapping",
"mappings": [ "&=> and "]
},
"replace_dot": {
"pattern": "\\.",
"type": "pattern_replace",
"replacement": " "
}
},
"filter": {
"my_stop": {
"type": "stop",
"stopwords": _spanish_
},
"my_stopwords": {
"type": "stop",
"stopwords": [ "the", "a" ]
}
},
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": [ "html_strip", "&_to_and", "replace_dot" ],
"tokenizer": "standard",
"filter": [ "lowercase", "my_stopwords", "my_stop" ]
}
}
},
...
}
}
1.4 索引類型的字段映射
索引模板中洽议,映射字段所對應(yīng)的常用結(jié)構(gòu)是:
"mappings": {
"my_type": { // 索引下的類型 my_type 應(yīng)用該映射
"dynamic_templates": [ ... ], // 動態(tài)映射部分宗收,用于未定義的 my_type 下字段
"properties": { ... } // 自定義字段的響應(yīng)映射
}
}
"my_type" 是索引下的一個類型,如果采用上述定義的索引模板亚兄,則索引下僅僅 my_type 類型應(yīng)用了該索引模板镜雨。如果想要索引下的所有模板應(yīng)用定義的映射,則可以將 "my_type" 替換成 "default" 字段儿捧。
1.4.1 動態(tài)映射
動態(tài)映射 "dynamic_templates" 字段對應(yīng)的是一個數(shù)組荚坞,數(shù)組中的元素是一個個字段的映射模板。每個字段的映射模板都有一個名字用戶描述這個模板的用途菲盾,一個 mapping 字段由于指明這個映射如何使用颓影,和至少一個參數(shù)(例如 match)來定義這個模板適用于哪個字段。
dynamic_templates 字段對應(yīng)的字段模板結(jié)構(gòu)如下:
{
"string_fields": { // 字段映射模板的名稱懒鉴,一般為"類型_fields"的命名方式
"match": "*", // 匹配的字段名為所有
"match_mapping_type": "string", // 限制匹配的字段類型诡挂,只能是 string 類型
"mapping": { ... } // 字段的處理方式
}
如下為一個定義實例:
"mappings": {
"my_type": {
"dynamic_templates": [
{
"string_fields": { // 字段映射模板的名稱碎浇,一般為"類型_fields"的命名方式
"match": "*", // 匹配的字段名為所有
"match_mapping_type": "string", // 限制匹配的字段類型,只能是 string 類型
"mapping": {
"fielddata": { "format": "disabled" }, // fielddata 不可用璃俗,對于分析字段奴璃,其默認(rèn)值是可用
"analyzer": "only_words_analyzer", // 字段采用的分析器名,默認(rèn)值為 standard 分析器
"index": "analyzed", // 索引方式定義為索引城豁,默認(rèn)值是分析
"omit_norms": true, // omit_norms 為真表示考慮字段的加權(quán)苟穆,可分析字段默認(rèn)值 false
"type": "string", // 字段類型限定為 string
"fields": { // 定義一個嵌套字段,將該字段應(yīng)用于不分析的場景
"raw": {
"ignore_above": 256, // 忽略字段對應(yīng)的值長度大于256的字段
"index": "not_analyzed", // 索引方式為不分析
"type": "string", // 字段的類型為 string
"doc_values": true // 對于不分析字段唱星,doc_values 對應(yīng)的是一種列式存儲結(jié)構(gòu)雳旅,默認(rèn)false
}
}
}
}
},
...
],
"properties": { ... }
}
}
可以看到间聊,內(nèi)部的字段模板的 mapping 字段下包含 fielddata攒盈、analyzer、index哎榴、omit_norms型豁、type、fields 等六個字段尚蝌,下面分別解釋這六個字段偷遗。
對于基本的 Elasticsearch 做個了解,一般的 es 用戶搜索字段驼壶,其反應(yīng)數(shù)據(jù)非常快喉酌,接近實時热凹,這個效果得益于其倒排索引的數(shù)據(jù)結(jié)構(gòu),然而倒排索引這個數(shù)據(jù)結(jié)構(gòu)在做聚合分析時泪电,卻不是那么容易般妙。因而在做傳統(tǒng)分析時,需要一種我們常見的行式存儲結(jié)構(gòu)相速,這一結(jié)構(gòu)在排序和巨額和分析時碟渺,具有明顯的優(yōu)勢。這一部分詳見 Elasticsearch 搜索與聚合在數(shù)據(jù)存儲結(jié)構(gòu)方面的理解 突诬。
fielddata 這一字段就是對于分析字段苫拍,除了倒排索引的數(shù)據(jù)存儲方式,仍定義一種形式上看著是行式結(jié)構(gòu)的存儲樣式旺隙,數(shù)據(jù)存儲在內(nèi)存中绒极,用于對字段的排序和聚合分析。對于分析字段 fielddata 的默認(rèn)值是可用的蔬捷。如果確定一個分析字段不需要排序或者聚合分析垄提,則該字段就設(shè)置為不可用榔袋。這樣可以節(jié)省內(nèi)存。
analyzer 定義的是該字段的分析器铡俐,默認(rèn)的分析器是 standard 標(biāo)準(zhǔn)分析器凰兑,這個地方可定義為自定義的分析器。
index 定義的是字段的索引方式审丘。默認(rèn)的 吏够,Elasticsearch 對字段采取的是分析索引,即會對字段進行倒排索引备恤。
omit_norms 定義的是字段在分析過程中稿饰,是否考慮加權(quán)。例如如果權(quán)重為2露泊,字段出現(xiàn)的頻率在計算時會翻倍喉镰,以提高計算的匹配度。對于分析字段侣姆,默認(rèn)的是不考慮加權(quán)。
type 定義的是字段的數(shù)據(jù)類型川蒙。
fields 是字段應(yīng)以一個嵌入字段畜眨。以 title 字段為例贰健,Elasticsearch 會自動生成兩個字段氓侧,分別是 title 和 title.raw 尝蠕。這樣,在有可能同時需要分詞和不分詞結(jié)果的環(huán)境标锄,就可以很靈活的使用不同的索引字段星压。比如,查看標(biāo)題中最常用的單詞军洼,應(yīng)該是使用 title 字段爷耀,查看閱讀數(shù)最多的文章標(biāo)題,應(yīng)該是使用 title.raw 字段锄贼。
ignore_above 字段是索引時忽略長度超過定義值的字段。
doc_values 字段與 fielddata 相對應(yīng),都是為了字段方便排序和聚合分析而重新定義的一種數(shù)據(jù)存儲方式蚯舱,不同的是兄裂,fielddata 應(yīng)用于分析字段廊营,存儲在內(nèi)存中道川;doc_values 應(yīng)用于不分析字段尊流,存儲于磁盤中。
上述是針對字段數(shù)據(jù)類型為 string 的動態(tài)模板定義崖技,對于其他數(shù)據(jù)類型,其動態(tài)模板的定義方式一般如下:
{
"float_fields": { // 命名方式 "類型_fields"
"match": "*"瞎访,
"match_mapping_type": "float",
"mapping": {
"type": "float",
"doc_values": true // doc_values 定義為 true,便于排序與聚合分析
}
}
}
1.4.2 自定義字段映射
針對索引類型中存在的字段拾徙,除了可以采用動態(tài)模板的方式古徒,還可以采用定義定義的方式读恃,常見的自定義結(jié)構(gòu)如下:
"mappings": {
"my_type": {
"dynamic_templates": [ ... ],
"properties": {
"user_city": { // 字段名
"analyzer": "lowercase_analyzer", // 字段分析器
"index": "analyzed", // 字段索引方式定義索引
"type": "string", // 字段數(shù)據(jù)類型定義為 string
"fields": { // 定義一個名為 user_city.raw 的嵌入的不分析字段
"raw": {
"ignore_above": 512,
"index": "not_analyzed",
"type": "string"
}
}
}隧膘,
"money":{
"type": "double",
"doc_values": true
}
...
}
}
}
復(fù)雜一些的是 string 類型的字段,對于其他類型的字段西雀,定義方式類似于上述的 money 字段定義方式萨驶。
1.5 別名
即使你認(rèn)為現(xiàn)在的索引設(shè)計已經(jīng)是完美的了,當(dāng)你的應(yīng)用在生產(chǎn)環(huán)境使用時艇肴,還是有可能在今后有一些改變的腔呜。所以請做好準(zhǔn)備:在應(yīng)用中使用別名而不是索引。然后你就可以在任何時候重建索引再悼。別名的開銷很小核畴,應(yīng)當(dāng)廣泛使用。利用索引別名冲九,可以實現(xiàn)零停機時間重新索引谤草。
定義方式如下:
{
"order": 0, // 模板優(yōu)先級
"template": "sample_info*", // 模板匹配的名稱方式
"settings": {...}, // 索引設(shè)置
"mappings": {...}, // 索引中各字段的映射定義
"aliases": {
"my_index":{}
}
}
零停機時間實現(xiàn)重新索引方式:
POST /_aliases
{
"actions": [
{ "remove": { "index": "my_index_v1", "alias": "my_index" }},
{ "add": { "index": "my_index_v2", "alias": "my_index" }}
]
}