Elasticsearch系列(6)Mapping之動態(tài)映射

1. 介紹

動態(tài)映射(Dynamic Mapping)是指當(dāng)Elasticsearch遇到文檔中之前未遇到的字段偶宫,會自動檢測及確定字段的數(shù)據(jù)類型并自動把新字段的類型添加到映射中的過程躯畴。
舉個例子:

PUT my_index/_doc/1 
{ "count": 5 }

執(zhí)行上面的PUT調(diào)用批钠,Elasticsearch會創(chuàng)建一個my_index索引刨疼,包含名字為count的字段悉默,字段數(shù)據(jù)類型為long间螟,并自動把新的字段類型添加到映射中纤垂,索引my_index的mapping信息如下所示:

GET my_index/_mappings
{}
# 返回的mapping信息
{
  "my_index" : {
    "mappings" : {
      "properties" : {
        "count" : {
          "type" : "long"
        }
      }
    }
  }
}
動態(tài)參數(shù)設(shè)置

通過設(shè)置參數(shù)dynamic夕晓,可以在文檔和對象級別控制動態(tài)映射的這種行為宛乃,參數(shù)dynamic可以設(shè)置為下列三種值:
(1)true:將新的檢測到的字段添加到映射中。(默認(rèn))
(2)false:忽略新檢測到的字段。這些字段將不會被索引征炼,因此不能被搜索析既,但仍然會出現(xiàn)在返回命中的_source字段中。這些字段將不會添加到映射中谆奥,新的字段必須顯式添加眼坏。
(3)strict:如果檢測到新字段,則拋出異常并拒絕索引文檔酸些。新字段必須顯式地添加到映射中宰译。

  • 操作示例如下:
# 1 - dynamic設(shè)置為strict,并且是類型級別魄懂,表示不會動態(tài)添加top級字段
# 2 - user 對象繼承類型級別設(shè)置
# 3 - dynamic設(shè)置為true沿侈,并且是對象級別,表示social_networks對象可以動態(tài)添加字段
PUT my_index
{
  "mappings": {
    "dynamic": "strict", // 1
    "properties": { 
      "user": {              // 2
        "properties": {
          "social_networks": { 
            "dynamic": "true", // 3
            "properties": {}
          }
        }
      }
    }
  }
}

如果啟用了動態(tài)字段映射市栗,Elasticsearch采用一些規(guī)則來確定JSON字段對應(yīng)的數(shù)據(jù)類型缀拭,規(guī)則包括動態(tài)字段映射(Dynamic field mappings)和動態(tài)模板集(Dynamic templates)。

2. 動態(tài)字段映射

動態(tài)字段映射(Dynamic field mappings):動態(tài)字段的檢測映射規(guī)則肃廓。

動態(tài)字段映射規(guī)則

JSON數(shù)據(jù)類型 Elasticsearch數(shù)據(jù)類型
null 無字段添加
true或false boolean類型
浮點數(shù) float類型
整數(shù) long類型
對象 object類型
數(shù)組 取決于數(shù)組中第一個非空值
字符串 date類型(日期檢測)智厌、double類型诲泌、
long類型(數(shù)字檢測)盲赊、text類型、
keyword 類型

只有上面這些數(shù)據(jù)類型會被動態(tài)檢測敷扫,所有其他數(shù)據(jù)類型必須顯式地映射哀蘑。

日期檢測

如果啟用了date_detection(默認(rèn)啟用),那么將檢查新的字符串字段葵第,看它們的內(nèi)容是否匹配dynamic_date_formats中指定的任何日期模式绘迁。如果找到匹配項,將添加相應(yīng)格式的一個新日期字段卒密。

  • 參數(shù)dynamic_date_formats 默認(rèn)格式為
    [ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]

舉個例子:

# 創(chuàng)建索引缀台,未指定字段類型
PUT my_index_01/_doc/1
{"create_date":"2015/09/02"}
# 查看索引的映射
GET my_index_01/_mapping 
# 返回結(jié)果,表示已經(jīng)動態(tài)映射為日期類型
{
  "my_index_01" : {
    "mappings" : {
      "properties" : {
        "create_date" : {
          "type" : "date",
          "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
        }
      }
    }
  }
}
禁用日期檢測

如果禁用了日期檢測哮奇,那么Elasticsearch遇到日期格式的字符串膛腐,會動態(tài)映射到其他類型(text或keyword),通過設(shè)置參數(shù)date_detection等于false來禁用動態(tài)日期檢測鼎俘。示例如下:

# 禁用date_detection
PUT my_index_01
{"mappings":{"date_detection":false}}
# 創(chuàng)建索引哲身,未指定字段類型
PUT my_index_01/_doc/1
{"create_date":"2015/09/02"}
# 查看索引的映射
GET my_index_01/_mapping 
# 返回結(jié)果,表示已經(jīng)動態(tài)映射為text類型
{
  "my_index_01" : {
    "mappings" : {
      "date_detection" : false,
      "properties" : {
        "create_date" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}
自定義檢測日期格式

可以自定義動態(tài)檢測的日期格式贸伐。示例如下:

PUT my_index_01
{"mappings":{"dynamic_date_formats":["MM/dd/yyyy"]}}

數(shù)字檢測

雖然JSON支持本地浮點數(shù)和整數(shù)數(shù)據(jù)類型勘天,但一些應(yīng)用程序或語言有時可能將數(shù)字呈現(xiàn)為字符串。通常正確的解決方案是顯式映射這些字段,但數(shù)字檢測(默認(rèn)禁用)可以自動做到這一點脯丝,示例如下:

# 開啟數(shù)字檢測
PUT my_index_01
{"mappings":{"numeric_detection":true}}
PUT my_index_01/_doc/1
{"my_float":"1.0","my_integer":"1"}
GET my_index_01/_mapping
{}
# 返回結(jié)果商膊,字段 my_float 映射為float類型,字段 my_integer 映射為long類型
{
  "my_index_01" : {
    "mappings" : {
      "numeric_detection" : true,
      "properties" : {
        "my_float" : {
          "type" : "float"
        },
        "my_integer" : {
          "type" : "long"
        }
      }
    }
  }
}

3. 動態(tài)模板集

動態(tài)模板集(Dynamic templates):用于自定義規(guī)則來為動態(tài)添加的字段配置映射巾钉。
動態(tài)模板集是一個命名object類型的數(shù)組翘狱,包含至少一個動態(tài)模板,結(jié)構(gòu)示例如下:

# 雙斜線在執(zhí)行時需要去掉
PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [ //1
      {
        "integers": { // 2
          "match_mapping_type": "long", //3
          "mapping": { // 4
            "type": "integer"
          }
        }
      }
    ]
  }
}
  • 注釋1-動態(tài)模板集參數(shù)名為dynamic_templates砰苍,數(shù)據(jù)類型是支持object的數(shù)組潦匈。
  • 注釋2-動態(tài)模板名稱自定義。
  • 注釋3-匹配條件赚导,包括match_mapping_type, match, match_pattern, unmatch, path_match, path_unmatch茬缩。
  • 注釋4-匹配字段使用的類型映射。

動態(tài)模板集包含幾類重要參數(shù):
(1)match_mapping_type作用于檢測數(shù)據(jù)類型吼旧。
(2)match和unmatch或match_pattern作用于字段的名稱凰锡。
(3)path_match和path_unmatch作用于字段的完整點路徑。
可以在動態(tài)模板集中的映射使用占位符{name}和{dynamic_type}圈暗, {name}表示原始字段名掂为,{dynamic_type}表示檢測到的數(shù)據(jù)類型。

驗證動態(tài)模板集

在建立索引應(yīng)用動態(tài)模板集或更新動態(tài)模板集時员串,Elasticsearch會對動態(tài)模板集的映射片段進(jìn)行驗證勇哗,驗證流程如下:

如果在映射片段中使用了{(lán)name}占位符,則在更新動態(tài)模板集時跳過驗證寸齐,這是因為更新時字段名是未知的欲诺。但是在建立索引時應(yīng)用模板時會進(jìn)行驗證。

處理動態(tài)模板集
  • 如果動態(tài)模板集中存在多個模板時渺鹦,會按照順序處理模板扰法,第一個匹配的模板將會使用。
  • 當(dāng)通過put mapping API放置新的動態(tài)模板集時毅厚,所有現(xiàn)有的模板都會被覆蓋塞颁。并且允許動態(tài)模板集在添加后被重新排序或刪除。
match_mapping_type
  • match_mapping_type對應(yīng)的值是JSON解析器檢測到的數(shù)據(jù)類型吸耿。因為JSON不區(qū)分long和integer或者double和float祠锣,所以它總是選擇更寬的數(shù)據(jù)類型,比如long表示整數(shù)珍语,double表示浮點數(shù)锤岸。
  • match_mapping_type數(shù)據(jù)類型有下列幾種會被自動檢測到:
    • 當(dāng)值為true或false時,類型為boolean板乙。
    • 當(dāng)啟用日期檢測并找到與任何配置的日期格式匹配的字符串值時是偷,類型為date拳氢。
    • 當(dāng)值有小數(shù)部分的數(shù)字,類型為double蛋铆。
    • 當(dāng)值沒有小數(shù)部分的數(shù)字馋评,類型為long。
    • 當(dāng)值為對象或散列結(jié)構(gòu)時刺啦,類型為object留特。
    • 當(dāng)值為字符串時,類型為string玛瘸。
      此外蜕青,符號*可以用于匹配所有數(shù)據(jù)類型。
      例如糊渊,將所有整數(shù)字段映射為integer類型而不是long類型右核,將所有字符串字段映射為text類型和keyword類型,可使用以下模板:
PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "template1": {
          "match_mapping_type": "long",
          "mapping": {
            "type": "integer"
          }
        }
      },
      {
        "template2": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "text",
            "fields": {
              "raw": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    ]
  }
}

PUT my_index_01/_doc/1
{"my_integer":5,"my_string":"Some string"}
match和unmatch
  • match參數(shù)使用模式對字段名進(jìn)行匹配渺绒,而unmatch使用模式來排除通過match匹配的字段贺喝。
    例如,匹配所有字段名稱以long_開頭的字符串字段(排除以_text結(jié)尾的)宗兼,并將它們映射為long字段躏鱼,可使用以下模板:
PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "longs_as_strings": {
          "match_mapping_type": "string",
          "match": "long_*",
          "unmatch": "*_text",
          "mapping": {
            "type": "long"
          }
        }
      }
    ]
  }
}
PUT my_index_01/_doc/1
{"long_num":"5","long_text":"foo"}
match_pattern
  • match_pattern參數(shù)用來調(diào)整match參數(shù)的行為,可以在字段名上支持完整的Java正則表達(dá)式匹配殷绍,例如:
PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "pattern_as_strings": {
          "match_mapping_type": "string",
          "match_pattern": "regex",
          "match": "^long_\\d+$",
          "mapping": {
            "type": "long"
          }
        }
      }
    ]
  }
}
# 字段long_1映射為long類型染苛,字段long_text映射為text或keyword類型
PUT my_index_01/_doc/1
{"long_1":"5","long_text":"foo"}
path_match和path_unmatch
  • path_match和path_unmatch參數(shù)的工作方式與match和unmatch相同,但操作在字段的完整點路徑上篡帕,而不僅僅是字段名稱殖侵。
    例如:
PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_name": {
          "path_match": "name.*",
          "path_unmatch": "*.middle",
          "mapping": {
            "type": "text",
            "copy_to": "full_name"
          }
        }
      }
    ]
  }
}
PUT my_index_01/_doc/1
{"name":{"first":"John","middle":"Winston","last":"Lennon"}}

上面例子將字段名為name的對象中所有子級字段(排除子級middle字段)的值復(fù)制到頂層的full_name字段贸呢,創(chuàng)建新的字段full_name镰烧,復(fù)制內(nèi)容到full_name字段中,但是不會影響_source字段內(nèi)容楞陷。

{name}和{dynamic_type}

占位符{name}被替換為字段名怔鳖,占位符{dynamic_type}被替換為檢測到的動態(tài)字段類型。
例如固蛾,將所有字符串字段設(shè)置為使用與字段同名的分析器结执,并對所有非字符串字段禁用doc_values,可使用以下模板:

PUT my_index_01
{
  "mappings": {
    "dynamic_templates": [
      {
        "named_analyzers": {
          "match_mapping_type": "string",
          "match": "*",
          "mapping": {
            "type": "text",
            "analyzer": "{name}"
          }
        }
      },
      {
        "no_doc_values": {
          "match_mapping_type": "*",
          "mapping": {
            "type": "{dynamic_type}",
            "doc_values": false
          }
        }
      }
    ]
  }
}
# english字段被映射為english分析器的text類型字段艾凯。
# count字段被映射為禁用doc_values的long類型字段献幔。
PUT my_index_01/_doc/1
{"english":"Some English text","count":5}

4. 結(jié)語

Elasticsearch的動態(tài)映射功能已完成了基本介紹,后續(xù)在應(yīng)用環(huán)境中需要根據(jù)實際情況靈活運(yùn)用趾诗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載蜡感,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者蹬蚁。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市郑兴,隨后出現(xiàn)的幾起案子犀斋,更是在濱河造成了極大的恐慌,老刑警劉巖情连,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叽粹,死亡現(xiàn)場離奇詭異,居然都是意外死亡却舀,警方通過查閱死者的電腦和手機(jī)虫几,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挽拔,“玉大人持钉,你說我怎么就攤上這事±槲簦” “怎么了每强?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長州刽。 經(jīng)常有香客問我空执,道長,這世上最難降的妖魔是什么穗椅? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任辨绊,我火速辦了婚禮,結(jié)果婚禮上匹表,老公的妹妹穿的比我還像新娘门坷。我一直安慰自己,他們只是感情好袍镀,可當(dāng)我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布默蚌。 她就那樣靜靜地躺著,像睡著了一般苇羡。 火紅的嫁衣襯著肌膚如雪绸吸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天设江,我揣著相機(jī)與錄音锦茁,去河邊找鬼。 笑死叉存,一個胖子當(dāng)著我的面吹牛码俩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歼捏,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼稿存,長吁一口氣:“原來是場噩夢啊……” “哼够傍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挠铲,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤冕屯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拂苹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體安聘,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年瓢棒,在試婚紗的時候發(fā)現(xiàn)自己被綠了浴韭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡脯宿,死狀恐怖念颈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情连霉,我是刑警寧澤榴芳,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站跺撼,受9級特大地震影響窟感,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜歉井,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一柿祈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哩至,春花似錦躏嚎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至菜谣,卻和暖如春珠漂,著一層夾襖步出監(jiān)牢的瞬間晚缩,已是汗流浹背尾膊。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留荞彼,地道東北人冈敛。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像鸣皂,于是被迫代替她去往敵國和親抓谴。 傳聞我的和親對象是個殘疾皇子暮蹂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,666評論 2 350