Mapping簡(jiǎn)介
mapping 是用來定義文檔及其字段的存儲(chǔ)方式阻课、索引方式的策略叫挟,主要作用如下:
- 定義index下的字段名。
- 定義字段類型限煞,比如數(shù)值型抹恳、浮點(diǎn)型、布爾型等署驻。
- 定義倒排索引相關(guān)的設(shè)置奋献,比如是否索引、記錄position等旺上。
也就是說映射決定了Elasticsearch在建立倒排索引瓶蚂、進(jìn)行檢索時(shí)對(duì)文檔采取的相關(guān)策略,如數(shù)字類型宣吱、日期類型窃这、文本類型等等。
需要注意的是:檢索時(shí)用到的分析策略凌节,要和建立索引時(shí)的分析策略相同钦听,否則將導(dǎo)致數(shù)據(jù)不準(zhǔn)確。
ES對(duì)不同的類型有不同的存儲(chǔ)和檢索策略
full text 全文檢索
- 比如: 對(duì)full text型的數(shù)據(jù)類型(如text)倍奢,在索引時(shí)朴上,會(huì)經(jīng)過各類處理 (包括分詞、normalization(時(shí)態(tài)轉(zhuǎn)換卒煞、單復(fù)數(shù)的轉(zhuǎn)換痪宰、同義詞轉(zhuǎn)換、大小寫轉(zhuǎn)換、縮寫)等處理)衣撬,才會(huì)建立到索引數(shù)據(jù)中乖订,更深入的話NPL自然語(yǔ)義處理。
exact value 精確匹配
- 再比如: 對(duì)exact value(如date)具练,在索引的分詞階段乍构,會(huì)將整個(gè)value作為一個(gè)關(guān)鍵詞建立到倒排索引中。
Mapping Type
每個(gè)索引都擁有唯一的 mapping type
扛点,用來決定文檔將如何被索引哥遮。mapping type
由下面兩部分組成
Meta-fields
元字段用于自定義如何處理文檔的相關(guān)元數(shù)據(jù)。 元字段的示例包括文檔的_index陵究,_type眠饮,_id和_source字段。Fields or properties
映射類型包含與文檔相關(guān)的字段或?qū)傩缘牧斜怼?/p>
數(shù)據(jù)類型
核心數(shù)據(jù)類型
- 字符串型:text铜邮、keyword
- 數(shù)值型:long仪召、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ù)類型
- 數(shù)組類型:array
- 對(duì)象類型:object
- 嵌套類型:nested object
地理位置數(shù)據(jù)類型
- geo_point
- geo_shape
專用類型
- 記錄:ip
- 實(shí)現(xiàn)自動(dòng)補(bǔ)全:completion
- 記錄分次數(shù):token_count
- 記錄字符串hash值:murmur3
- percolator
- join
多字段特性 multi-fields
允許對(duì)同一個(gè)字段采用不同的配置胁后,比如分詞,常見例子如對(duì)人名實(shí)現(xiàn)拼音搜索嗦枢,只需要在人名中新增一個(gè)字段為pinyin即可
詳見:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
針對(duì)同一字段支持多種字段類型可以更好地滿足我們的搜索需求攀芯,例如一個(gè)string類型的字段可以設(shè)置為text來支持全文檢索,與此同時(shí)也可以讓這個(gè)字段擁有keyword類型來做排序和聚合文虏,另外我們也可以為字段單獨(dú)配置分詞方式侣诺,例如"analyzer": "ik_max_word"
text 類型
text類型的字段用來做全文檢索,例如郵件的主題氧秘、淘寶京東中商品的描述等年鸳。這種字段在被索引存儲(chǔ)前先進(jìn)行分詞,存儲(chǔ)的是分詞后的結(jié)果丸相,而不是完整的字段搔确。text字段不適合做排序和聚合。如果是一些結(jié)構(gòu)化字段,分詞后無意義的字段建議使用keyword類型膳算,例如郵箱地址座硕、主機(jī)名、商品標(biāo)簽等涕蜂。
常有參數(shù)包含以下:
- analyzer:用來分詞华匾,包含索引存儲(chǔ)階段和搜索階段(其中查詢階段可以被search_analyzer參數(shù)覆蓋),該參數(shù)默認(rèn)設(shè)置為index的analyzer設(shè)置或者standard analyzer机隙。
- index:是否可以被搜索到蜘拉,默認(rèn)是true。
- fields:Multi-fields允許同一個(gè)字符串值同時(shí)被不同的方式索引黍瞧,例如用不同的analyzer使一個(gè)field用來排序和聚類上忍,另一個(gè)同樣的string用來分析和全文檢索。
- search_analyzer:這個(gè)字段用來指定搜索階段時(shí)使用的分詞器敦锌,默認(rèn)使用analyzer的設(shè)置订歪。
- search_quote_analyzer:搜索遇到短語(yǔ)時(shí)使用的分詞器,默認(rèn)使用search_analyzer的設(shè)置年局。
- store:是否在source之外存儲(chǔ)际看,每個(gè)文檔索引后會(huì)在ES中保存一份原始文檔,存放在source中矢否,一般情況下不需要設(shè)置store為true仲闽,因?yàn)樵趕ource中已經(jīng)有一份原始文檔了。
keyword 類型
keyword用于索引結(jié)構(gòu)化內(nèi)容(例如電子郵件地址僵朗,主機(jī)名赖欣,狀態(tài)代碼,郵政編碼或標(biāo)簽)的字段验庙,這些字段被拆分后不具有意義顶吮,所以在es中應(yīng)索引完整的字段,而不是分詞后的結(jié)果粪薛。
通常用于過濾(例如在博客中根據(jù)發(fā)布狀態(tài)來查詢所有已發(fā)布文章)悴了,排序和聚合。keyword只能按照字段精確搜索违寿,例如根據(jù)文章id查詢文章詳情湃交。如果想根據(jù)本字段進(jìn)行全文檢索相關(guān)詞匯,可以使用text類型藤巢。
PUT my_index
{
"mappings": {
"properties": {
"tags": {
"type": "keyword"
}
}
}
}
常有參數(shù)包含以下:
- index:是否可以被搜索到搞莺,默認(rèn)是true。
- fields:Multi-fields允許同一個(gè)字符串值同時(shí)被不同的方式索引掂咒,例如用不同的analyzer使一個(gè)field用來排序和聚類腮敌,另一個(gè)同樣的string用來分析和全文檢索阱当。
- null_value:如果該字段為空,設(shè)置的默認(rèn)值糜工,默認(rèn)為null弊添。
- ignore_above:設(shè)置索引字段大小的閾值。該字段不會(huì)索引大小超過該屬性設(shè)置的值捌木,默認(rèn)為2147483647油坝,代表著可以接收任意大小的值。但是這一值可以被PUT Mapping Api中新設(shè)置的ignore_above來覆蓋這一值刨裆。
date類型
支持排序澈圈,且可以通過format
字段對(duì)時(shí)間格式進(jìn)行格式化。
json
中沒有時(shí)間類型帆啃,所以在es在規(guī)定可以是以下的形式:
- 一段格式化的字符串瞬女,例如
"2015-01-01"
或者"2015/01/01 12:10:30"
- 一段
long
類型的數(shù)字,指距某個(gè)時(shí)間的毫秒數(shù)努潘,例如1420070400001
- 一段
integer
類型的數(shù)字诽偷,指距某個(gè)時(shí)間的秒數(shù)
object類型
mapping
中不用特意指定field為object
類型,因?yàn)檫@是它的默認(rèn)類型疯坤。
json
類型天生具有層級(jí)的概念报慕,文檔內(nèi)部還可以包含object
類型進(jìn)行嵌套。例如:
PUT my_index/_doc/1
{
"region": "US",
"manager": {
"age": 30,
"name": {
"first": "John",
"last": "Smith"
}
}
}
在es中上述對(duì)象會(huì)被按照以下的形式進(jìn)行存儲(chǔ):
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John",
"manager.name.last": "Smith"
}
對(duì)象數(shù)組:
{
"authors": [
{"age": 26 , "name": "jock white"},
{"age": 55 , "name": "tom jones"},
{"age": 39 , "name": "kitty smith"}
]
}
對(duì)象數(shù)組在es中的存儲(chǔ)格式:
{
"authors.age": [26, 55, 39],
"authors.name": [jock, white, tom, jones, kitty, smith]
}
mapping可以對(duì)不同字段進(jìn)行不同的設(shè)置
PUT my_index
{
"mappings": {
"properties": {
"region": {
"type": "keyword"
},
"manager": {
"properties": {
"age": { "type": "integer" },
"name": {
"properties": {
"first": { "type": "text" },
"last": { "type": "text" }
}
}
}
}
}
}
}
nest類型
nest
類型是一種特殊的object
類型压怠,它允許object
可以以數(shù)組形式被索引眠冈,而且數(shù)組中的某一項(xiàng)都可以被獨(dú)立檢索。
而且es中沒有內(nèi)部類的概念菌瘫,而是通過簡(jiǎn)單的列表來實(shí)現(xiàn)nest
效果蜗顽,例如下列結(jié)構(gòu)的文檔:
PUT my_index/_doc/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
上面格式的對(duì)象會(huì)被按照下列格式進(jìn)行索引,因此會(huì)發(fā)現(xiàn)一個(gè)user中的兩個(gè)屬性值不再匹配雨让,alice和white失去了聯(lián)系
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}
range類型
支持以下范圍類型:
類型 | 范圍 |
---|---|
integer_range |
-2的31次 到 2的31次-1 . |
float_range | 32位單精度浮點(diǎn)數(shù) |
long_range |
-2的63次 到 2的63次-1 . |
double_range | 64位雙精度浮點(diǎn)數(shù) |
date_range | unsigned 64-bit integer milliseconds |
ip_range | ipv4和ipv6或者兩者的混合 |
使用范例為:
PUT range_index
{
"settings": {
"number_of_shards": 2
},
"mappings": {
"properties": {
"age_range": {
"type": "integer_range"
},
"time_frame": {
"type": "date_range",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
PUT range_index/_doc/1?refresh
{
"age_range" : {
"gte" : 10,
"lte" : 20
},
"time_frame" : {
"gte" : "2015-10-31 12:00:00",
"lte" : "2015-11-01"
}
}
注:term是查詢時(shí)對(duì)關(guān)鍵字不分詞诫舅,keyword是索引時(shí)不分詞。
自定義Mapping
自定義Mapping的api如下:
- Mapping中的字段類型一旦設(shè)定后宫患,禁止直接修改,原因是:
- Lucence實(shí)現(xiàn)的倒排索引生成后不允許修改这弧,
- 除非重新建立新的索引娃闲,然后做reindex操作。
- 允許新增字段匾浪。
- 通過dynamic參數(shù)來控制字段的新增:
- true(默認(rèn))允許自動(dòng)新增字段皇帮。
- false不允許自動(dòng)新增字段,但是文檔可以正常寫入蛋辈,但無法對(duì)字段進(jìn)行查詢等操作属拾。
- strict 文檔不能寫入将谊,報(bào)錯(cuò)。
copy_to
index
- 控制當(dāng)前字段是否索引渐白,默認(rèn)為true尊浓,即記錄索引,false不記錄纯衍,即不可搜索栋齿。
- 當(dāng)身份證號(hào)和手機(jī)號(hào)這樣的敏感信息被搜索的時(shí)候,可以設(shè)置為false襟诸,這樣就可以不用建立倒排索引節(jié)省空間瓦堵。
index_options
-
index_options用于控制倒排索引記錄的內(nèi)容,有如下4中配置:
- docs:只記錄doc id歌亲。
- freqs:記錄doc id和term frequencies菇用。
- positions:記錄doc id、term frequencies和term position陷揪。
- offsets:記錄doc id惋鸥、term frequencies、term position和character offsets鹅龄。
- text類型默認(rèn)配置為positions揩慕,其他默認(rèn)為docs。
記錄內(nèi)容越多扮休,占用空間越大迎卤。
index_options的設(shè)定如下所示:
null_value
- 當(dāng)字段遇到null值時(shí)的處理策略,默認(rèn)為null玷坠,即空值蜗搔,此時(shí)es會(huì)忽略該值“吮ぃ可以通過設(shè)定該值設(shè)定字段的默認(rèn)值樟凄。
dynamic Mapping
es可以自動(dòng)識(shí)別文檔字段類型,從而降低用戶使用成本兄渺,如下所示:
es是依靠json文檔的字段類型來實(shí)現(xiàn)自動(dòng)識(shí)別字段類型缝龄,支持的類型有:
JSON類型 | ES類型 |
---|---|
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的子字段 |
日期的自動(dòng)識(shí)別可以自行配置日期格式叔壤,以滿足各種需求
- 默認(rèn)是["strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy/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可以關(guān)閉日期自動(dòng)識(shí)別的機(jī)制
字符串是數(shù)字時(shí)口叙,默認(rèn)不會(huì)自動(dòng)識(shí)別為整型炼绘,因?yàn)樽址谐霈F(xiàn)數(shù)字時(shí)完全合理的
-
numeric_detection可以開啟字符串中數(shù)字的自動(dòng)識(shí)別,如下所示:
Dynamic Template
允許根據(jù)es自動(dòng)識(shí)別的數(shù)據(jù)類型妄田、字段名等來動(dòng)態(tài)設(shè)定字段類型俺亮,可以實(shí)現(xiàn)如下效果:
- 所有字符串類型都設(shè)定為keyword類型驮捍,即默認(rèn)不分詞
- 所有以message開頭的字段都設(shè)定為text類型,即分詞
- 所有以long_開頭的字段都設(shè)定為long類型
- 所有自動(dòng)匹配為double類型的都設(shè)定為float類型脚曾,以節(jié)省空間
匹配規(guī)則一般有如下幾個(gè)參數(shù):
- match_mapping_type匹配es自動(dòng)識(shí)別的字段類型东且,如boolean,long斟珊,string等
- match苇倡,unmatch匹配字段名
- path_match,path_unmatch匹配路徑
以message開頭的字段都設(shè)定為text類型
double類型的都設(shè)定為float類型,節(jié)省空間
自定義mapping的建議
自定義Mapping的操作步驟如下:
- 1囤踩、寫入一條文檔到es的臨時(shí)索引中旨椒,獲取es自動(dòng)生成的mapping
- 2、修改步驟1得到的mapping堵漱,自定義相關(guān)配置
- 3综慎、使用步驟2的mapping創(chuàng)建實(shí)際所需索引
索引模板
英文為Index Template,主要用于在新建索引時(shí)自動(dòng)應(yīng)用預(yù)先設(shè)定的配置勤庐,簡(jiǎn)化索引創(chuàng)建的操作步驟示惊。
- 可以設(shè)定索引的配置和mapping。
- 可以有多個(gè)模板愉镰,根據(jù)order設(shè)置米罚,order大的覆蓋小的配置。
type底層結(jié)構(gòu)及棄用原因
type是什么
type丈探,是一個(gè)index中用來區(qū)分類似的數(shù)據(jù)的录择,類似的數(shù)據(jù),但是可能有不同的fields碗降,而且有不同的屬性來控制索引建立隘竭、分詞器.
field的value,在底層的lucene中建立索引的時(shí)候讼渊,全部是opaque bytes類型动看,不區(qū)分類型的。
lucene是沒有type的概念的爪幻,在document中菱皆,實(shí)際上將type作為一個(gè)document的field來存儲(chǔ),即type挨稿,es通過type來進(jìn)行type的過濾和篩選仇轻。
es中不同type存儲(chǔ)機(jī)制
一個(gè)index中的多個(gè)type,實(shí)際上是放在一起存儲(chǔ)的叶组,因此一個(gè)index下,不能有多個(gè)type重名历造,而類型或者其他設(shè)置不同的甩十,因?yàn)槟菢邮菬o法處理的船庇。
{
"goods": {
"mappings": {
"electronic_goods": {
"properties": {
"name": {
"type": "string"
},
"price": {
"type": "double"
},
"service_period": {
"type": "string"
}
}
},
"fresh_goods": {
"properties": {
"name": {
"type": "string"
},
"price": {
"type": "double"
},
"eat_period": {
"type": "string"
}
}
}
}
}
}
PUT /goods/electronic_goods/1
{
"name": "小米空調(diào)",
"price": 1999.0,
"service_period": "one year"
}
PUT /goods/fresh_goods/1
{
"name": "澳洲龍蝦",
"price": 199.0,
"eat_period": "one week"
}
es文檔在底層的存儲(chǔ)是這樣子的
{
"goods": {
"mappings": {
"_type": {
"type": "string",
"index": "false"
},
"name": {
"type": "string"
}
"price": {
"type": "double"
}
"service_period": {
"type": "string"
},
"eat_period": {
"type": "string"
}
}
}
}
底層數(shù)據(jù)存儲(chǔ)格式
{
"_type": "electronic_goods",
"name": "小米空調(diào)",
"price": 1999.0,
"service_period": "one year",
"eat_period": ""
}
{
"_type": "fresh_goods",
"name": "澳洲龍蝦",
"price": 199.0,
"service_period": "",
"eat_period": "one week"
}
type棄用原因
- 同一索引下,不同type的數(shù)據(jù)存儲(chǔ)其他type的field 大量空值侣监,造成資源浪費(fèi)鸭轮。
- 不同類型數(shù)據(jù),要放到不同的索引中橄霉。
- es9中窃爷,將會(huì)徹底刪除type。
分詞器Analyzer
作用:切分詞語(yǔ)姓蜂,normalization提升recall召回率按厘。
recall,召回率:搜索的時(shí)候钱慢,增加能夠搜索到的結(jié)果的數(shù)量逮京。
分詞器是Elasticsearch中專門處理分詞的組件,英文為Analyzer束莫,其組成如下:
Character Filters
針對(duì)原始文本進(jìn)行處理懒棉,比如去除html特殊標(biāo)記符。Tokenizer
將原始文本按照一定規(guī)則切分為單詞览绿。Token Filters
針對(duì)Tokenizer處理的單詞進(jìn)行在加工策严,比如轉(zhuǎn)小寫,刪除或新增等處理饿敲。
stop word妻导,停用詞:了、的诀蓉、呢等栗竖。
一個(gè)分詞器很重要,將一段文本進(jìn)行各種處理渠啤,最后處理好的結(jié)果才會(huì)拿去建立倒排索引狐肢。
測(cè)試分詞:
GET /_analyze
{
"analyzer":"standard",
"text":"Text to analyze 70"
}
返回值:
{
"tokens" : [
{
"token" : "text",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "to",
"start_offset" : 5,
"end_offset" : 7,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "analyze",
"start_offset" : 8,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "70",
"start_offset" : 16,
"end_offset" : 18,
"type" : "<NUM>",
"position" : 3
}
]
}
token:實(shí)際存儲(chǔ)term關(guān)鍵字。
position:在此詞條原文本中的位置沥曹。
start_offset/end_offset:字符在原始字符串中的位置份名。
分詞器最佳實(shí)踐
因?yàn)楹罄m(xù)的keyword
和text
設(shè)計(jì)分詞問題,這里給出分詞最佳實(shí)踐妓美。即索引時(shí)用ik_max_word僵腺,搜索時(shí)分詞器用ik_smart,這樣索引時(shí)最大化的將內(nèi)容分詞壶栋,搜索時(shí)更精確的搜索到想要的結(jié)果辰如。
例如我想搜索的是小米手機(jī),我此時(shí)的想法是想搜索出小米手機(jī)的商品贵试,而不是小米音響琉兜、小米洗衣機(jī)等其他產(chǎn)品凯正,也就是說商品信息中必須只有小米手機(jī)這個(gè)詞。