mapping 映射


es的映射就相當於編程語言中給變量定義類型,定義后的變量使用起來更高效,未定義的變量相較於定義的性能肯定是不如的。所以需要掌握es映射。

未定義映射es會對提供的數據進行類型猜測,如果對自動判斷的類型及參數設置不滿意,或者需要使用一些更高級的映射設置,那么就需要使用自定義映射。

添加映射格式:

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

創建my_text3索引

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

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

一個索引對應一個映射,一個索引下多個type無法對應多個映射的。7.0版本以后,索引下的type類型就棄用了。最主要原因為了提高性能,具體原因參考官網和此文檔鏈接


一、字段數據類型:

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

常用類型:

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

為不同目的以不同方式索引相同字段通常很有用。例如,string可以將字段索引為全文搜索類型text和精確搜索類型keyword,以及用於排序或聚合的字段numeric


二、索引設置(settings):

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

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?pretty

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


三、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不被索引被存儲。

更多字段參考官方文檔


四、多重索引

多重索引只用於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" }
    }
}

官方文檔


五、自定義映射

示例

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。以減少磁盤開銷

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


六、動態映射

在使用之前不需要定義字段和映射類型,適合剛入門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
        }
      }
    }
  }
}

更多配置參數請參考官網


七、修改映射

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

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

如果需要修改字段映射,則需要使用reindex功能。還請參考另外博文

八、索引模版

前面內容中的動態模版是針對字段進行動態匹配。現在有這樣一種情況,同一類型的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM