1. 類型斷定json
ElasticSearch在建立index的時候是能夠不指定schema的,那麼它是怎麼知道你使用的是什麼類型呢?實際上它是經過給定 document的json來斷定的,例如,string的話是用引號引發來的,數字是光溜溜的,boolean類型是true或者false等等。這個 規則很是的簡單,可是很是有效。例若有以下的json:bash
{ "field1": "hello", "field2": 1024 }
ES可以很容易斷定field1爲string類型,field2爲數字類型,可是有些狀況下,須要把全部的格式都存爲string,true和 false就不行了,由於ES會優先將其存爲boolean類型,這就須要咱們手動指定schema,另一個問題是,若是咱們對某個index首次插入 數據的時候爲某個field插入了一個數字類型,例如:app
curl -XPUT localhost:9200/blog/article/1?pretty -d '{ "field1" : 1024}'
咱們能夠查看其mapping:curl
curl -XGET localhost:9200/blog/_mapping?pretty
咱們能夠看到其schem以下:ide
{ "blog" : {
"article" : {
"properties" : {
"field1" : {
"type" : "long",
"ignore_malformed" : false
}
}
}
}
}
這說明ES已經將該字段的類型定義爲long了,而後若是咱們插入string,那麼就會報錯,說類型不匹配:url
curl -XPUT localhost:9200/blog/article/2?pretty -d '{
"field1" : "test string"
}'
返回結果爲:spa
{ "error" : "MapperParsingException[Failed to parse [field1]];
nested: NumberFormatException[For input string:
\"test string\"]; ", "status" : 400 }
可是,若是繼續插入float型數據是能夠的,由於long能夠轉換爲float,以下:日誌
curl -XPUT localhost:9200/blog/article/2?pretty -d '{
"field1" : 3.14
}'
這時,咱們在查看schema,能夠看到ES將schema修改了。這就會對咱們的數據精度形成影響,爲了防止這種狀況,或者爲了防止已經存在的index添加字段,咱們能夠將動態schema關閉,以下:orm
{ "blog" : { "article" : { "dynamic" : "false", "properties" : { ... } } } }
2.動態mappingblog
有時,咱們須要經過json中的field和type來決定咱們使用的mapping,這時,動態templates就派上用場了。動態 templates和普通的mapping相似,它有一個本身的模式,若是一個field的名字匹配了該模式,該template就會使用,下面是定義模 式的兩種手段:
match: template在field名匹配的時候起用。
unmatch: template在field名不匹配的時候起用。
固然,也可使用path_match和path_unmatch對嵌套field使用。
定義field的使用可使用
{name}: document最初寫入數據的field的名字。
{dynamic_type}: document最初寫入數據的field的type。
須要提醒的是,ES是按照你寫的templates的順序來匹配的,所以,匹配範圍越廣的應該放在越後,否則就會將全部後面的正則攔掉了。例如*應該放在最後:
{ "mappings" : { "article" : { "dynamic_templates" : [ { "template_test": { "match" : "*", "mapping" : { "type" : "multi_field", "fields" : { "{name}": { "type" : "{dynamic_type}"}, "str": {"type" : "string"} } } } }] } } }
例如我在logstash的日誌發現了一個錯誤,以下
"response"=>"-"
"error"=>"MapperParsingException[failed to parse [response];
nested: NumberFormatException[For input string: \"-\"; "
,這是由於我以前在mapping中定義了response爲long類型,如今寫入的數據中出現了response=> "-",致使報錯類型不匹配。
{
"dynamic_templates" : [ {
"response_fields": {
"match" : "*",
"mapping" : {
"type" : "multi_field",
"fields" : {
"response": { "type" : "long"}, "str": {"type" : "string"}
}
}
}
}
}
文章原鏈:http://www.dengchuanhua.com/