關於動態Mappin-多字段映射

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/

相關文章
相關標籤/搜索