前言
我們知道古瓤,我們是在
ElasticSearch
(簡(jiǎn)稱ES)上創(chuàng)建索引文檔后止剖,哪怕我們之前沒有指定字段的類型,但ES還是會(huì)給我們的文檔數(shù)據(jù)給予相對(duì)應(yīng)的字段屬性落君,這背后是什么原理呢穿香?同時(shí),ES中又提供了哪些常見的數(shù)據(jù)類型給我們使用呢绎速?是否可以自定義Mapping
模板來方便自己使用呢皮获?本篇文章將圍繞ES的Mapping
配置來對(duì)上面的問題進(jìn)行一一解答,希望可以對(duì)這方面不熟悉的讀者一個(gè)參考纹冤。
注意:文章中的演示版本為Elastic Search7.6.1
洒宝,具體的語法各位讀者以自己本地的es版本為準(zhǔn)
一、Mapping簡(jiǎn)介
Mapping類似于數(shù)據(jù)庫(kù)中的表結(jié)構(gòu)定義赵哲,我們可以通過它來定義Index下的字段名(Field Name )、定義字段的類型君丁,比如數(shù)值型枫夺、字符串型、布爾型等绘闷、定義倒排索引相關(guān)的配置橡庞,比如是否索引、記錄position等
PUT /mapping_index
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
}
}
}
}
二印蔗、自定義Mapping的API介紹
(一)Dynamic 新增字段嚴(yán)格性
Mappings的API介紹如下:
Mapping 中的字段類型一旦設(shè)定后扒最,禁止直接修改,因?yàn)長(zhǎng)ucene實(shí)現(xiàn)的倒排索引生成后不允許修改华嘹。原因也很好理解吧趣,如果可以隨意更改字段類型的話,會(huì)影響倒排索引的使用耙厚,試想一下强挫,如果一個(gè)字段原先是text類型,如果變更成keyword類型的話薛躬,原先已有的倒排索引就要重新reindex后才能繼續(xù)使用俯渤。
但是ES允許我們對(duì)已有的索引進(jìn)行新增字段的操作,具體的實(shí)現(xiàn)方式是通過dynamic
參數(shù)來定義的型宝。
dynamic-value | 含義 |
---|---|
true(默認(rèn)) | 允許自動(dòng)新增字段 |
false | 不允許自動(dòng)新增字段八匠,但是文檔可以正常寫入絮爷,但無法對(duì)字段進(jìn)行查詢等操作 |
strict | 文檔不能寫入,報(bào)錯(cuò) |
(二)copy_to 字段復(fù)制
copy_to 可以將該字段的值復(fù)制到目標(biāo)字段梨树,實(shí)現(xiàn)類似于_all的作用
PUT /mapping_index
{
"mappings": {
"properties": {
"lastname": {
"type": "text",
"copy_to": "fullname"
},
"firstname": {
"type": "text",
"copy_to": "fullname"
},
"fullname": {
"type": "text"
}
}
}
}
PUT /mapping_index/_doc/1
{
"firstname": "xiaoming",
"lastname": "huang"
}
GET /mapping_index/_search
(三)index 控制字段是否可以索引
index
控制當(dāng)前字段是否索引坑夯,默認(rèn)為true,即記錄索引劝萤,false 不記錄渊涝,即不可搜索
那么我們一般可以在什么場(chǎng)景使用index呢?
當(dāng)ES的索引中存在某些證件號(hào)等敏感信息我們不希望被用作索引條件的時(shí)候床嫌,我們就可以將這個(gè)字段的index
屬性設(shè)為false跨释。同時(shí)該字段不作為倒排索引,會(huì)節(jié)省磁盤和內(nèi)存空間
(四)index_options
index_options
控制倒排索引記錄的內(nèi)容厌处,一共有4種配置可選鳖谈。
index_options-value | 含義 |
---|---|
doc | 只記錄文檔id(doc id ) |
freqs | 記錄doc id 和term frequences
|
positions |
doc id 、term frequences 、term position
|
offsets |
doc id 缓淹、term frequences 粪躬、term position 、character offsets
|
文本類型text
默認(rèn)的配置是positions
贯要,其他默認(rèn)是docs。需要注意的是椭住,雖然index_options提供了offsets這種內(nèi)容較多的配置級(jí)別崇渗,但是記錄的內(nèi)容越多,占用的空間也會(huì)越多京郑,在實(shí)際操作中還是要根據(jù)實(shí)際情況進(jìn)行配置宅广。
PUT /mapping_index
{
"mappings": {
"properties": {
"name": {
"type": "text",
"index_options": "offsets"
}
}
}
}
(五)Null_Value
null_value是當(dāng)字段遇到null值時(shí)的處理策略,默認(rèn)為null些举,即空值跟狱,此時(shí)es 會(huì)忽略該值』海可以通過設(shè)定該值設(shè)定字段的默認(rèn)值
三驶臊、Mapping數(shù)據(jù)類型
Mapping中給存儲(chǔ)的數(shù)據(jù)提供了字段類型來描述字段的屬性(這部分比較簡(jiǎn)單,就不進(jìn)行演示了~)
(一)核心數(shù)據(jù)類型
類型 | 可選項(xiàng) |
---|---|
字符串型 | text叼丑、keyword |
數(shù)值型 | tong资铡、integer、short幢码、byte.double笤休、float、half_float症副、scaled_float |
日期類型 | date |
布爾類型 | boolean |
二進(jìn)制類型 | binary |
范圍類型 | integer_range店雅、float_range政基、long_range、double_range闹啦、date_range |
(二)復(fù)雜數(shù)據(jù)類型
類型 | 可選項(xiàng) |
---|---|
數(shù)組類型 | array |
對(duì)象類型 | object |
嵌套類型 | nested object |
(三)地理位置數(shù)據(jù)類型
類型 | 可選項(xiàng) |
---|---|
經(jīng)緯度查詢 | geo_point |
對(duì)象類型 | object |
地理形狀查詢 | geo_shape |
(四)專用類型
類型 | 可選項(xiàng) |
---|---|
實(shí)現(xiàn)自動(dòng)補(bǔ)全 | completion |
記錄分詞數(shù) | token_count |
記錄字符串 hash值 | murmur3 |
(五)多字段特性:multi-fields
ES允許對(duì)同一個(gè)字段采用不同的配置沮明,比如分詞,常見例子如對(duì)人名實(shí)現(xiàn)拼音搜索窍奋,我們當(dāng)然可以在索引中新增一個(gè)字段荐健,單獨(dú)用于做人名的拼音,但是這樣拼音和人名就相互獨(dú)立開來了琳袄,缺少了關(guān)聯(lián)性江场,也不夠優(yōu)雅。通過Multi-Fields
窖逗,我們只需要在人名中新增一個(gè)子字段為pinyin即可.
PUT /mapping_index
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"pinyin": {
"type": "text",
"analyzer": "pinyin"
}
}
}
}
}
}
# 上面的拼音analyzer需要自己定義下
GET /mapping_index1/_search
{
"query": {
"match": {
"username.pinyin": "xiaoming"
}
}
}
四址否、Dynamic Mapping 動(dòng)態(tài)映射模板定義
(一)ES的文檔字段的自動(dòng)識(shí)別
我們?cè)谑褂肊S的過程中可以發(fā)現(xiàn),哪怕我們?cè)趧?chuàng)建文檔或者新增索引字段的時(shí)候沒有聲明字段的數(shù)據(jù)類型碎紊,ES還是會(huì)幫我們定義好比較符合需要的數(shù)據(jù)類型佑附。
那么ES是通過什么規(guī)則來進(jìn)行定義的呢?
答案是ES是依靠JSON文檔的字段類型來實(shí)現(xiàn)自動(dòng)識(shí)別字段類型的仗考,支持的類型如下:
JSON類型 | ES數(shù)據(jù)類型 |
---|---|
null | 忽略 |
boolean | boolean |
浮點(diǎn)類型 | float |
整數(shù) | long |
object | object |
array | 由第一個(gè)非null值的類型決定 |
string | 配為日期則設(shè)為date類型(默認(rèn)開啟)音同;匹配為數(shù)字的話設(shè)為float或 long類型(默認(rèn)關(guān)閉)設(shè)為text類型,并附帶keyword的子字段 |
PUT /mapping_index/_doc/1
{
"name": "小明",
"age": 15,
"birth": "1994-03-21",
"married": false,
"year": "15",
"tags": ["boy","fashion"],
"money": 100.3
}
- 日期和數(shù)字的自動(dòng)識(shí)別
ES默認(rèn)的日期識(shí)別格式是:[ "strict_date_optional_time" ,"yyyy/MM/dd HH:mm:ss Zllyyyy/MM/dd z"]
strict_date_optional_time是ISo datetime的格式秃嗜,完整格式類似下面:
YYYY-MM-DDThh:mm:ssTzD (eg 1997-07-16T19:20:30+01:00)
我們可以通過dynamic_date_formats
和date_detection
來實(shí)現(xiàn)可以自定義日期類型和關(guān)閉日期自動(dòng)識(shí)別的效果
PUT /mapping_index
{
"mappings": {
"dynamic_date_formats": ["MM/dd/yyyy"]
}
}
PUT /mapping_index/_doc/1
{
"birth": "04/03/2021"
}
GET /mapping_index/_mapping
(二)自定義字段映射模板
ElasticSearch
允許根據(jù)es 自動(dòng)識(shí)別的數(shù)據(jù)類型权均、字段名等來動(dòng)態(tài)設(shè)定字段類型,可以實(shí)現(xiàn)所有字符串類型都默認(rèn)設(shè)定為keyword類型痪寻,即默認(rèn)不分詞螺句、所有以long_開頭的字段都設(shè)定為long類型虽惭,即實(shí)現(xiàn)指定字符模糊匹配指定數(shù)據(jù)類型橡类、所有自動(dòng)匹配為double類型的都設(shè)定為float類型等功能。
匹配規(guī)則一般有以下三個(gè)參數(shù):
- match_mapping_type :匹配ES自動(dòng)識(shí)別的字段類型芽唇,比如boolean顾画、long、string等
- match匆笤,unmatch:匹配的字段名
- path_match研侣、path_unpath:匹配的路徑
PUT /mapping_index
{
"mappings": {
"dynamic_templates": [
{
"string_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
PUT /mapping_index
{
"mappings": {
"dynamic_templates": [
{
"string_as_keywords": {
"match" : "message*",
"mapping": {
"type" : "keyword"
}
}
}
]
}
}
PUT /mapping_index/_doc/1
{
"name": "xiaoming",
"message": "he is a boy"
}
GET /mapping_index/_mapping
(三)自定義Mapping的建議
自定義Mapping雖然可以實(shí)現(xiàn)定制化開發(fā),但是當(dāng)索引中需要定義的字段很多時(shí)炮捧,工作量還是不少庶诡。針對(duì)這種情況,可以參考下面這種做法:
- 不先直接定義文檔Mapping映射咆课,而是寫入一條文檔到es的臨時(shí)索引中末誓,獲取es自動(dòng)生成的mapping
- 根據(jù)步驟1得到的mapping基礎(chǔ)上扯俱,再調(diào)整自定義相關(guān)配置
- 使用步驟2的mapping創(chuàng)建實(shí)際所需索引
(四)索引模板
索引模板,英文為Index Template喇澡,主要用于在新建索引時(shí)自動(dòng)應(yīng)用預(yù)先設(shè)定的配置迅栅,簡(jiǎn)化索引創(chuàng)建的操作步驟。當(dāng)需要配置的索引自定義映射數(shù)量較多晴玖,規(guī)則相同時(shí)读存,我們就可以考慮將這條索引映射規(guī)則抽離成索引模板。需要注意的是呕屎,當(dāng)有多套索引模板存在時(shí)让簿,會(huì)根據(jù)order設(shè)置,order大的覆蓋小的配置榨惰。
PUT /_template/template_1
{
"index_patterns" : ["te*"],
"order" : 0,
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_source" : { "enabled" : false }
}
}
PUT /_template/template_2
{
"index_patterns" : ["tes*"],
"order" : 1,
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_source" : { "enabled" : true }
}
}
PUT test_index
GET test_index
刪除和獲取索引模板的API如下:
GET _template 查詢所有索引模板
GET _template/模板名稱 查詢指定的索引模板
DELETE _template/模板名稱 刪除指定的索引模板
寫在最后
關(guān)于ES的Mapping映射還有其他知識(shí)點(diǎn)拜英,有需要查詢Mapping其他屬性的讀者可以自行查詢ES官方文檔(這一塊不同版本的ES還是略有不同的)。文檔地址如下:
https://www.elastic.co/guide/en/elasticsearch/reference/7.x/indices-templates-v1.html