04.elasticsearch-dynamic_mapping_and_index_template
文章目錄
- 1. dynamic mapping 設置
- 1. es內部支持的field類型的動態識別
- 1. 默認的field 識別
- 2. date-detection
- 3. numeric-detection
- 2. 在mapping中設置動態的模板進行識別
- 1. data type + match_mapping_type
- 2. match_and_unmatch + field name
- 3. match_pattern + field name
- 4. path_match 和 path_unmatch + 帶點符號的field name
- 5. 使用filed name 和 dynamic_type 作為mapping param的設置
- 2. index template
- 1. 創建一個index template
- 2. 一個新的index命中多個index-template的規則
- 3. template中添加version
1. dynamic mapping 設置
dynamic mapping主要介紹了,es是如何根據indexing的doc來確定mapping的信息的,也就是根據每個json 屬性判斷mapping的每個field應該為什么類型。既然說了是dynamic mapping,也就是對應的mapping沒有定義,或者mapping存在但是沒有該field的情況,如果mapping中已經定義了,那么直接根據mapping中定義的type去嘗試解析即可。
json能夠表達的類型是有限的,只能表達以下類型
比如日期date,數字中的long,integer是分不清的。所以es需要對這些進行支持
1. es內部支持的field類型的動態識別
1. 默認的field 識別
null: No field is added.
true or false: boolean field
floating point number: float field
integer: long field
object: object field
array: Depends on the first non-null value in the array.
string: 這個看需要,正常情況下是一個帶有keyword的text的field,如果開啟了date-detection可能會產生date field mapping, 如果開啟了numeric-detection課可能會產生 long或者float field mapping.
需要注意的是小數都變成了float,沒有特殊識別double,integer,long都變成了long
long 是可以兼容integer,但是float卻是不能兼容double的
例如下面的請求
PUT my_index05/_doc/1 {"number":123446567890233123446567890233123446567890233123446567890233.6 }返回 {"error": {"root_cause": [{"type": "mapper_parsing_exception","reason": "failed to parse field [number] of type [float] in document with id '1'. Preview of field's value: '1.2344656789023312E59'"}],"type": "mapper_parsing_exception","reason": "failed to parse field [number] of type [float] in document with id '1'. Preview of field's value: '1.2344656789023312E59'","caused_by": {"type": "illegal_argument_exception","reason": "[float] supports only finite values, but got [Infinity]"}},"status": 400 }在沒有提前創建mapping的情況下回報錯,因為number字段的值超出了float的范圍
假如先定義mapping
則是可以成功寫入的。
2. date-detection
es對日期做了特殊支持,默認情況下滿足特定的格式的string進行indexing的時候可能會被識別為 date字段
默認情況下識別的日期格式是 [ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]
你也可以關掉這個設置
PUT my_index {"mappings": {"date_detection": false} }同時還可以自定義日期的格式
PUT my_index {"mappings": {"dynamic_date_formats": ["MM/dd/yyyy"]} }3. numeric-detection
這個會把string類型的數字轉換為數字,轉為float或者long 類型(double長度的會報錯)
這個設置默認情況下是關閉的
2. 在mapping中設置動態的模板進行識別
es還可以根據字段名,json數據原始類型等做一些更靈活的動態field映射,這種一般情況下都是通過特征進行設置,相對來說可能會一條規則對過個field都有效,所以叫dynamic templates
dynamic template 主要提供了一下集中方式進行template設置
1. data type + match_mapping_type
data type是es識別出來的json的數據類型,在上面已經有描述了,但是es默認增加了對日期的識別,所以有下面幾種
樣例
PUT my_index {"mappings": {"dynamic_templates": [{"integers": {"match_mapping_type": "long","mapping": {"type": "integer"}}},{"strings": {"match_mapping_type": "string","mapping": {"type": "text","fields": {"raw": {"type": "keyword","ignore_above": 256}}}}},{"my_float":{"match_mapping_type":"double", # 注意這個地方只有寫成double才能正確匹配,生成mapping中的field的type為double, 沒有這個配置的話默認生成的mapping field的type為float."mapping":{"type":"double"}}}]} }然后執行 PUT my_index/_doc/1 {"my_integer": 922337203685477580, "my_string": "Some string" }返回{"error": {"root_cause": [{"type": "mapper_parsing_exception","reason": "failed to parse field [my_integer] of type [integer] in document with id '1'. Preview of field's value: '922337203685477580'"}],"type": "mapper_parsing_exception","reason": "failed to parse field [my_integer] of type [integer] in document with id '1'. Preview of field's value: '922337203685477580'","caused_by": {"type": "i_o_exception","reason": "Numeric value (922337203685477580) out of range of int\n at [Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@56f5802a; line: 2, column: 35]"}},"status": 400 }這個會生成把long 強制設置為 integer(indexing的時候是long也不行),上面indexing的時候傳入了一個大于integer范圍的值,導致了失敗,假如改成小于integer范圍的就可以成功
假如我們直接把這個put語句應用到一個新的自動生成的索引當中,則是可以成功的
這個是可以成功的。
2. match_and_unmatch + field name
簡單的模式匹配,可以設置以什么開頭,以什么結尾的filed
樣例
PUT my_index {"mappings": {"dynamic_templates": [{"longs_as_strings": {"match_mapping_type": "string","match": "long_*","unmatch": "*_text","mapping": {"type": "long"}}}]} }PUT my_index/_doc/1 {"long_num": "5", "long_text": "foo" }3. match_pattern + field name
是上一個的增強版,filed name的模式匹配的時候允許使用正則表達式
樣例
PUT my_index {"mappings": {"dynamic_templates": [{"longs_as_strings": {"match_mapping_type": "string","match_pattern": "regex","match": "^long_*","unmatch": "*_text","mapping": {"type": "long"}}}]} }PUT my_index/_doc/1 {"long_num": "5", "long_text": "foo" }4. path_match 和 path_unmatch + 帶點符號的field name
直接看樣例
PUT my_index {"mappings": {"dynamic_templates": [{"full_name": {"path_match": "name.*","path_unmatch": "*.middle","mapping": {"type": "text","copy_to": "full_name"}}}]} }PUT my_index/_doc/1 {"name": {"first": "John","middle": "Winston","last": "Lennon"} }5. 使用filed name 和 dynamic_type 作為mapping param的設置
這個是什么意思呢,就是將field name 和dynamic_type作為變量,在設置mapping的時候可以直接引用
看一個樣例更容易理解
PUT my_index {"mappings": {"dynamic_templates": [{"named_analyzers": {"match_mapping_type": "string","match": "*","mapping": {"type": "text","analyzer": "{name}"}}},{"no_doc_values": {"match_mapping_type":"*","mapping": {"type": "{dynamic_type}","doc_values": false}}}]} }PUT my_index/_doc/1 {"english": "Some English text", "count": 5 }這里的string類型的屬性都會使用它的field name作為analyzer,比如 english 字段的analyzer 就是 english-analyzer ,這個局限性很強,因為只有有限數量的analyzer
其他類型的field的type直接使用es探測到的type
總感覺這個用處很小
2. index template
index template 的作用是什么呢,從字面意思上理解就是為index的mapping指定template使用的
他的功能是你定一個mapping,并且指定一些模式匹配規則,可以指定哪些index創建的時候使用這個mapping,他主要是對還未創建的索引起作用。
這個功能還是很有用的,比如在日志系統當中,一般是按照天創建索引,索引的mapping基本上是一致的,或者說只有有限的幾種,而且索引的name一般也都是根據一些規則組成的,所以就可以定義一些index template,在每次創建索引的時候不用再指定mapping,直接會根據index template創建mapping。
當然,在index template中不僅可以指定mapping,還可以指定所有正常創建index的時候使用的參數,包括alias,setting 等設置。
1. 創建一個index template
PUT _template/template_1 {"index_patterns": ["te*", "bar*"],"aliases" : {"kk-log" : { }},"settings": {"number_of_shards": 1},"mappings": {"_source": {"enabled": false},"properties": {"host_name": {"type": "keyword"},"created_at": {"type": "date","format": "EEE MMM dd HH:mm:ss Z yyyy"}}},"order" : 10 }這樣的話,所有以te,bar開頭的索引都會命中這個index-template,進而對應的index的會使用這個template中的設置。
在template的請求體中有以下比較重要的地方
2. 一個新的index命中多個index-template的規則
這個在上面說的差不多了,這里舉一個栗子來看看吧
PUT /_template/template_1 {"index_patterns" : ["test*"],"order" : 0,"settings" : {"number_of_shards" : 1},"mappings" : {"_source" : { "enabled" : false }} }PUT test_have01/_doc/1 {"my_integer": 922337203685477580, "my_string": "Some string" }GET test01/_search返回 {"took" : 0,"timed_out" : false,"_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 },"hits" : {"total" : { "value" : 1, "relation" : "eq" },"max_score" : 1.0,"hits" : [{"_index" : "test_have01","_type" : "_doc","_id" : "1","_score" : 1.0}]} }可以看到返回的直接沒有_source字段了。
增加一個order值更高的template,并打開source字段
PUT /_template/template_2 {"index_patterns" : ["test_have*"],"order" : 1,"settings" : {"number_of_shards" : 1},"mappings" : {"_source" : { "enabled" : true }} }再寫入文檔
PUT test_have01/_doc/1 {"my_integer": 922337203685477580, "my_string": "Some string" }GET test_have01/_search返回{"took" : 0,"timed_out" : false,"_shards" : { total" : 1, "successful" : 1, "skipped" 0, "failed" : 0 },"hits" : {"total" : { "value" : 1,@@relation" : "eq" },"max_score" : 1.0,"hits" : [{"_index" : "test_have01","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"my_integer" : 922337203685477580,"my_string" : "Some string"}}]} }可以看到template_2 中對_source字段的設置override 了temple_1中的設置,因為他的order值更大。
3. template中添加version
這個說事在外部系統管理template的時候使用
PUT /_template/template_1 {"index_patterns" : ["*"],"order" : 0,"settings" : {"number_of_shards" : 1},"version": 123 }等后面有實際的使用經驗了再來補充。
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的04.elasticsearch-dynamic_mapping_and_index_template的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 03.elasticsearch-map
- 下一篇: 05.elasticsearch-ind