mapping 映射

es的映射就至關於編程語言中給變量定義類型,定義後的變量使用起來更高效,未定義的變量相較於定義的性能確定是不如的。因此須要掌握es映射。html

未定義映射es會對提供的數據進行類型猜想,若是對自動判斷的類型及參數設置不滿意,或者須要使用一些更高級的映射設置,那麼就須要使用自定義映射。node

添加映射格式:android

curl -XPUT http://localhost:9200/索引名稱/類型名稱/_mapping?pretty -d '
{
  "properties":{
    "字段名稱":{
      "type":"字段類型",
      "store":"是否存儲",
      "index":"索引方式、是否分析"
      ...
    }
  }
}'

建立my_text3索引ios

PUT /my_text3
{
  "mappings": {
    "doc": {   #類型
      "properties": {
        "name":{   #字段名
          "type": "text"  #字段類型
        }
      }
    }
  }
}

mapping中字段可查詢官網:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.htmlnginx

一個索引對應一個映射,一個索引下多個type沒法對應多個映射的。7.0版本之後,索引下的type類型就棄用了。最主要緣由爲了提升性能,具體緣由參考官網和此文檔連接git


1、字段數據類型:

  • text,keyword,date,long,double,boolean,ip
  • 支持josn的分層特性類型:object,nested
  • 特殊類型: geo_point,geo_shape,completion
    更多類型參考官網文檔:連接

經常使用類型:github

  • text:文本類型,會對內容進行分詞,若是不指定分詞則使用默認的standard分詞器,支持模糊查詢。
  • keyword:關鍵字類型,不會對內容進行分詞,只能按其精確值搜索。一般用於過濾、排序和聚合。
  • date:時間類型
  • long,integer:整型
  • double,float:符點數
  • ip :地址類型,搜索時能夠位置搜索

爲不一樣目的以不一樣方式索引相同字段一般頗有用。例如,string能夠將字段索引爲全文搜索類型text和精確搜索類型keyword,以及用於排序或聚合的字段numeric編程


2、索引設置(settings):

用於控制與索引相關方面配置。如刷新間隔時間,主副分片數等json

PUT /my_text3
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  }
}
  • number_of_shards :主分片數,默認爲5,奇數。7.x版本後默認爲1。這裏使用單機作實驗,只用一個主分片便可
  • number_of_replicas :副本分片,默認爲1。當主分片丟失時,可用於數據恢復。這裏是單機實驗,無所謂副本分片。

查看索引settings:
GET /my_text3/_settings?prettyapp

更多的setting設置還請參考官網文檔
動態更新setting連接


3、Meta-fields

特殊字段,在索引映射中統一以_下劃線開頭。

查詢結果:

"hits" : {
    "total" : 1,
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "my_text3",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.5753642,
        "_source" : {
          "name" : "Kobe Bryant",
          "age" : 40
        }
      }
    ]
  }
}

常見元字段:

  • _id : 惟一標識
  • _index : 索引名,即文檔所在的索引
  • _score : 得分
  • _type : 文檔的類型名
  • _uid : _type和_id鏈接一塊兒構形成的複合主鍵
  • _source : 存儲文檔中全部字段的集合。默認爲true,若是設置爲false,那麼你將只能指定獲取字段搜索和結果。使用默認便可。你也能夠嘗試設置成false再query下試試。

默認狀況下,_uid字段是被存儲(可取回)和索引(可搜索)的。 _type字段被索引可是沒有存儲,_id_index字段則既沒有被索引也沒有被存儲,這意味着它們並非真實存在的。_source不被索引被存儲。

更多字段參考官方文檔


4、多重索引

多重索引只用於textkeyword類型。text字段用於搜索,不可用於排序,聚合等複雜操做。若是非要讓text便可搜索也可進行高級操做,帶來的代價一般是性能快速降低。因此建議給一個經常使用的字段定義兩種類型,搜索時使用text,高級操做時使用keyword

PUT /my_text5
{
  "mappings": {
    "doc": {
      "properties": {
        "name":{
          "type": "text",
          "norms":false,
          "fields": {
            "raw": {      #後綴,會額外生成name.raw的字段,類型爲keyword
              "type":"keyword",
              "ignore_above":20
            }
          }
        }
      }
    }
  }
}

###插入數據
POST /my_text5/doc/1
{
  "name":"walter dai"
}


###查詢數據
GET /my_text5/_search
{
  "query": {
    "term": {
      "name.raw": "walter dai"    #查詢name.raw也能夠查詢到數據
    }
  }
}

索引中未定義映射的字段,會默認映射成field(text類型)和field.keyword(keyword類型)兩種。若是大多數場景用精確查找,能夠反過來定義

"name": {
    "type": "keyword",
    "fields": {
        "text": { "type": "text" }
    }
}

官方文檔


5、自定義映射

示例

PUT /my_text4
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text",
        "index": true,
        "norms": false, 
        "analyzer": "standard",
        "search_analyzer": "standard"
      },
      "age":{
        "type": "integer"
      },
      "gender":{
        "type": "boolean"
      },
      "country": {
        "type": "keyword",
        "ignore_above": 40
      }
    }
  }
}
  • mappings : 映射
  • doc : _type默認類型。 連接
  • properties :類型映射,object字段和nested字段,並明肯定義。默認object
  • name : 索引中的字段名稱,下面括號中就是單獨給每一個字段配置屬性
  • type :type設置字段類型,text爲字符型,6.x廢棄string類型了,integer整形,boolean布爾型true或false,keyword關鍵字等。連接
  • analyzer,search_analyzer :analyzer存儲時的分析器,存儲數據時,根據什麼分析器來分析數據並倒排索引數據。search_analyzer是搜索時以什麼分析器分析搜索數據並去查詢匹配相應數據。存儲和搜索時的分析器得一致,不然搜索的結果可能不是想要的。
  • index : 區分三種,徹底爲了性能。
5.x前 5.x後 意思
index:analyzed type:text,index:true 分析字符串 ,全文索引。設置爲text後,默認爲true
index:not_analyzed type:keyword 精確搜索,不分析
index:no index:false 不索引,不可被搜索
  • analyzer:插入時分析器,text類型插入時,先分析,在創建倒排索引。
  • search_analyzer :搜索時分析器,搜索時先分析輸入數據,並根據評分排序搜索到的數據。

    elastic自帶standard,whitesapce,english,simple分析器。如在配置映射時不指定分析器,則默認使用standard分析器。通常analyzer和search_analyzer得一致,否則搜索就可能會得不到想要的結果。中文可以使用ik分詞器。analyzer詳細使用還請參考其它博文

  • ignore_above : 超過的字符將不被索引或存儲,限定大小
  • norms : 默認爲true,做用是當計算得分時,是否把字段長度用做參數計算。若是此字段僅用於聚合或者過濾,你應該設置爲false。以減小磁盤開銷

此處簡單列舉了些我的經常使用的配置,詳細的配置還請參數官方文檔。


6、動態映射

在使用以前不須要定義字段和映射類型,適合剛入門elk時使用,索引以logstash-開頭就會默認使用動態映射。(程序自帶的模版映射)
動態映射只適用於對數據不瞭解的狀況下使用,不然爲了數據的壓縮和性能,咱們都應該儘可能不使用動態映射,除非像nginx request中帶有不少個參數,須要將參數抽取出來時,就須要使用動態映射了。請求中的參數過多而沒法一一列舉出來。

可動態識別 datebooleanfloatlongobjectarraystring(string分爲text和keyword)

不能夠動態識別的類型,如ip:

PUT /my_text1/doc/10     #試先沒有建立,my_text1的映射,直接PUT數據
{
  "ipp": "192.168.10.3" 
}

GET /my_text1/_mapping   #查看映射
{
  "my_text1" : {
    "mappings" : {
      "doc" : { 
        "properties" : {   #默認的雙引號內的數據爲text和keyword類型
          "ipp" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
...

正常狀況下,當你自定義映射時,就應該考慮到每一個字段的類型,是否須要索引,聚合等一系列後續操做。若是有無法定義的類型數據時,才須要使用dynamic配置項,不然你應該或儘量給每個數據類型定義好。

dynamic支持三種選項:

  • true : 默認值,當有未定義的字段插入時,elastic動態判斷類型,不管判斷是否成功。都將字段添加到映射中。
  • flase :未定義的字段插入時,將會被忽略,不被索引。可是會存儲至_source字段裏
  • strict :未定義字段插入時,拋出異常並拒絕文檔。

示例:將全部未定義的字段只映射爲keyword類型

PUT /my_text6
{
  "mappings": {
    "doc": {
      "dynamic_templates":[    #方括號內是定義動態映射規則
        {
          "message_field":{    #名稱
            "match":"*",       #匹配哪些字段,*表示全部未定義的字段。還能夠用 match_pattern的正則匹配,glob匹配規則,umatch不匹配某些字段等等
            "mapping":{        #映射成什麼類型
                "type":"keyword",
                "ignore_above":256
            }
          } 
        }
      ],
      "properties":{    #明肯定義字段映射
        "name":{
          "type":"text",
          "norms":false
        }
      }
    }
  }
}

更多配置參數請參考官網


7、修改映射

mapping中已經定義的字段類型,一旦建立,不能修改,不能刪除,只能夠新增字段。

PUT /my_text3/doc/_mapping     #使用_mapping接口新增字段映射
{
  "properties": {
    "age": {       #以前索引中沒有的字段
      "type": "integer"
    }
  }
}

若是須要修改字段映射,則須要使用reindex功能。還請參考另外博文

8、索引模版

前面內容中的動態模版是針對字段進行動態匹配。如今有這樣一種狀況,同一類型的nginx日誌,可是存儲進es時會有不少索引,這時咱們要爲每個索引都先PUT一個映射,而後才能存儲數據。這時爲了方便同一類型的索引,就可使用索引模版,定義一個 n-開頭的索引名都引用同一個映射。

模版映射API:

GET /_cat/templates
GET /_cat/templates?name=xxx    #查詢某個模版
DELETE /_template/xxx     #刪除模版

個人nginx模版:

curl -XPUT "http://node2003:9200/_template/nginx" -H 'Content-Type: application/json' -d'
{
  "order": 10,      #優先級,值越大,優先級越高。默認爲0
  "index_patterns": "n-*",    #匹配索引的格式,只要匹配上都使用此模版映射
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
      "doc":{
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "agent": {
          "type": "keyword",
          "ignore_above": 256
        },
           "city_domain_name":{
                "type":"keyword",
                "ignore_above":256
            },
        "android_version": {
          "type": "keyword"
        },
        "ios_version": {
          "type": "keyword"
        },
        "body_bytes_sent": {
          "type": "integer"
        },
        "http_referer": {
          "type": "text",
          "norms": false,
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "http_x_forwarded_for": {
          "type": "keyword"
        },
        "httpversion": {
          "type": "keyword",
          "index": false
        },

        "remote_addr": {
          "type": "ip"
        },
        "request": {
          "type": "text",
          "norms": false,
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "request_body": {
          "type": "text",
          "norms": false
        },
        "request_method": {
          "type": "keyword",
          "ignore_above": 10
        },
        "request_time": {
          "type": "float"
        },
        "scheme": {
          "type": "keyword",
          "ignore_above": 20
        },
        "status": {
          "type": "integer"
        },
        "upstream_addr": {
          "type": "keyword"
        },
        "upstream_cache_status": {
          "type": "keyword"
        },
        "upstream_response_time": {
          "type": "float"
        }   
      }
    }
  }
}'


總結:

mapping映射是很是重要。我的總結若有錯誤,還望指正。

官方連接:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html

相關文章
相關標籤/搜索