前言
一般的, mapping 可以分為 動態映射(dynamic mapping) 和 靜態(顯示) 映射 (explicit mapping) 和精准(嚴格) 映射(strict mapping)
具體由dynamic 屬性控制
動態映射(dynamic: true)
創建一個索引
PUT m1 { "mappings": { "doc":{ "properties": { "name": { "type": "text" }, "age": { "type": "long" } } } } }
通過 GET m1/_mapping 看一下 mappings 信息:
{ "m1" : { "mappings" : { "doc" : { "dynamic" : "true", "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text" } } } } } }
添加一些數據,並且新增一個sex字段:
PUT m1/doc/1 { "name": "小黑", "age": 18, "sex": "不詳" }
此時看下 mappings
{ "m1" : { "mappings" : { "doc" : { "dynamic" : "true", # ES 默認允許添加新的字段 "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text" }, "sex" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } } } } }
注意: mappings 一旦創建,則無法修改。因為Lucene 生成倒排索引后就不能改了
靜態映射(dynamic:false)
現在,我們將 dynamic 值設置為 false
PUT m2 { "mappings": { "doc":{ "dynamic":false, "properties": { "name": { "type": "text" }, "age": { "type": "long" } } } } }
現在測試一下false 和 true 有什么區別
PUT m2/doc/1 { "name": "小黑", "age":18 } PUT m2/doc/2 { "name": "小白", "age": 16, "sex": "不詳" }
第二條數據相對於第一條數據,多了一個sex屬性,我們可以用sex來做為條件查詢一下:
GET m2/doc/_search { "query": { "match": { "sex": "不詳" } } }
結果為空 為什么呢?
我們再此查一下mappings 結果在mappings中並沒有 sex字段的映射關系。
所以查不到。 但是存儲時會存儲該字段。 相當於能寫 不能 查
嚴格模式(dynamic:strict)
同樣 創建一個 mappings
PUT m3 { "mappings": { "doc": { "dynamic": "strict", "properties": { "name": { "type": "text" }, "age": { "type": "long" } } } } }
添加兩篇文檔
PUT m3/doc/1 { "name": "小黑", "age": 18 } PUT m3/doc/2 { "name": "小白", "age": 18, "sex": "不詳" }
第一篇文檔添加和查詢都沒問題。但是,當添加第二篇文檔的時候,就報錯了
也就是 連寫都不能寫
小結
- 動態映射(dynamic:true):動態添加新的字段(或缺省)。
- 靜態映射(dynamic:false):忽略新的字段。在原有的映射基礎上,當有新的字段時,不會主動的添加新的映射關系,只作為查詢結果出現在查詢中。
- 嚴格模式(dynamic: strict):如果遇到新的字段,就拋出異常。
一般靜態映射用的較多。就像HTML
的img
標簽一樣,src
為自帶的屬性,你可以在需要的時候添加id
或者class
屬性。
當然,如果你非常非常了解你的數據,並且未來很長一段時間不會改變,strict
不失為一個好選擇。