[TOC]
一疾宏、定義
映射(mapping)即是模式定義(schema definition)宵蕉。一個(gè)映射定義了字段類型室抽,每個(gè)字段的數(shù)據(jù)類型,以及字段被 Elasticsearch 處理的方式巡扇。映射還用于設(shè)置關(guān)聯(lián)到類型上的元數(shù)據(jù)。
可以說(shuō)垮衷,映射就是對(duì)索引庫(kù)中索引的字段名稱及其數(shù)據(jù)類型進(jìn)行定義厅翔,類似于 mysql 中的表結(jié)構(gòu)信息。
映射可以分為動(dòng)態(tài)映射和顯式映射搀突。
1.1刀闷、動(dòng)態(tài)映射 (dynamic mapping)
在關(guān)系數(shù)據(jù)庫(kù)中,需要事先創(chuàng)建數(shù)據(jù)庫(kù)仰迁,然后在該數(shù)據(jù)庫(kù)實(shí)例下創(chuàng)建數(shù)據(jù)表甸昏,然后才能在該數(shù)據(jù)表中插入數(shù)據(jù)。而 ElasticSearch中 不需要事先定義映射(Mapping)徐许,文檔寫入 ElasticSearch 時(shí)施蜜,會(huì)根據(jù)文檔字段自動(dòng)識(shí)別類型,這種機(jī)制稱之為動(dòng)態(tài)映射雌隅。
# 動(dòng)態(tài)映射:如果 mapping 沒有創(chuàng)建翻默,elasticsearch 將會(huì)根據(jù)寫入的數(shù)據(jù)的 key 自行創(chuàng)建相應(yīng)的 mapping,并寫入數(shù)據(jù)
curl -H "Content-Type: application/json" -XPUT localhost:9200/sports/basketball/123 -d '
{
"date": "2018-05-20",
"title": "Cavaliers",
"content": "They are real Cavaliers tonigiht",
"author_id": 520
}'
# 可以使用 _mapping 查詢索引的 mapping
curl -XGET localhost:9200/sports/basketball/_mapping?pretty
# 返回結(jié)果
{
"sports" : {
"mappings" : {
"basketball" : {
"properties" : {
"author_id" : {
"type" : "long"
},
"content" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"date" : {
"type" : "date"
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
}
1.2恰起、顯式映射(explicit mappings)
在 ElasticSearch 中也可以事先定義好映射修械,包含文檔的各個(gè)字段及其類型等,這種方式稱之為顯式映射村缸。
# 靜態(tài)映射祠肥,手動(dòng)設(shè)置
curl -H "Content-Type: application/json" -XPUT localhost:9200/books?pretty -d '
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
},
"mappings": {
"novel": {
"properties": {
"title": {
"type": "text"
},
"name": {
"type": "text",
"analyzer": "standard",
"search_analyzer": "standard"
},
"publish_date": {
"type": "date"
},
"price": {
"type": "double"
},
"number": {
"type": "integer"
}
}
}
}
}'
ES 通過猜測(cè)來(lái)確定字段類型,動(dòng)態(tài)映射將會(huì)很有用梯皿,但如果需要對(duì)某些字段添加特殊屬性(如:定義使用其它分詞器仇箱、是否分詞、是否存儲(chǔ)等)东羹,就必須顯式映射剂桥。
二、數(shù)據(jù)類型及支持屬性
2.1属提、核心類型(Core datatype)
字符串:string
权逗,string 類型包含 text 和 keyword。ELasticsearch 5.X 之后的字段類型不再支持 string冤议,由 text 或 keyword 取代斟薇。
- text:當(dāng)一個(gè)字段是要被全文搜索的,比如 Email 內(nèi)容恕酸、產(chǎn)品描述堪滨,應(yīng)該使用 text 類型。設(shè)置 text 類型以后蕊温,字段內(nèi)容會(huì)被分析袱箱,在生成倒排索引以前遏乔,字符串會(huì)被分析器分成一個(gè)一個(gè)詞項(xiàng)。text 類型的字段不用于排序发笔,很少用于聚合(termsAggregation 除外)盟萨。
- keyword:該類型不需要進(jìn)行分詞,可以被用來(lái)檢索過濾了讨、排序和聚合捻激,keyword 類型的字段只能通過精確值搜索到(不可用 text 分詞后的模糊檢索)。
整數(shù):byte
, short
, integer
, long
浮點(diǎn)數(shù):float
, double
布爾:boolean
日期:date
量蕊,JSON 本身并沒有日期數(shù)據(jù)類型灵寺,在 ES 中的日期類型可以是:
- 類似
2015-01-01
or2015/01/01 12:10:30
的字符串 - long 類型的毫秒級(jí)別的時(shí)間戳
- int 類型的秒級(jí)別的時(shí)間戳
- 日期類型默認(rèn)會(huì)被轉(zhuǎn)換為 UTC 并且轉(zhuǎn)換為毫秒級(jí)別的時(shí)間戳的 long 類型存儲(chǔ)黍聂。日期類型如果不指定 format 吃度,將會(huì)以默認(rèn)格式表示归形。
二進(jìn)制型:`binary``酪我,二進(jìn)制類型以 Base64 編碼方式接收一個(gè)二進(jìn)制值翘县,二進(jìn)制類型字段默認(rèn)不存儲(chǔ)杀饵,也不可搜索系吭。
除 text 類型以外脉漏,其他類型必須要進(jìn)行精確查詢苞冯,因?yàn)槌?text 外其他類型不會(huì)進(jìn)行分詞。
# 新增
curl -H "Content-Type: application/json" -XPOST localhost:9200/books/novel/1 -d '
{
"name": "being alive",
"number": "1000",
"price": 17.99,
"publish_date": "2018-05-20",
"title": "being Live"
}'
# 新增
curl -H "Content-Type: application/json" -XPOST localhost:9200/books/novel/2 -d '
{
"name": "baby",
"number": "100",
"price": 27.99,
"publish_date": "2018-05-16",
"title": "a girl is a baby"
}'
# date 類型不會(huì)進(jìn)行分詞侧巨,必須精確查詢舅锄,此時(shí)查詢不出數(shù)據(jù)
curl -XGET localhost:9200/books/novel/_search?q=publish_date:2018
# 返回結(jié)果
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 3,
"successful": 3,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
# date 類型不會(huì)進(jìn)行分詞,必須精確查詢司忱,此時(shí)可以查詢出數(shù)據(jù)
curl -XGET localhost:9200/books/novel/_search?q=publish_date:2018-05-20
# 返回結(jié)果
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 3,
"successful": 3,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "books",
"_type": "novel",
"_id": "1",
"_score": 1,
"_source": {
"name": "being alive",
"number": "1000",
"price": 17.99,
"publish_date": "2018-05-20",
"title": "being Live"
}
}
]
}
}
# text 會(huì)進(jìn)行分詞皇忿,此時(shí)可以查出數(shù)據(jù)
curl -XGET localhost:9200/books/novel/_search?q=title:girl
# 返回結(jié)果
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 3,
"successful": 3,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "books",
"_type": "novel",
"_id": "2",
"_score": 0.2876821,
"_source": {
"name": "baby",
"number": "100",
"price": 27.99,
"publish_date": "2018-05-16",
"title": "a girl is a baby"
}
}
]
}
}
2.2、復(fù)合類型(Complex datatypes)
2.2.1坦仍、對(duì)象
JSON 文檔是有層次結(jié)構(gòu)的鳍烁,一個(gè)文檔可能包含其他文檔,如果一個(gè)文檔包含其他文檔繁扎,那么該文檔值是對(duì)象類型幔荒,其數(shù)據(jù)類型是對(duì)象,ES 默認(rèn)把文檔的屬性 type設(shè)置為 object梳玫,即 "type":"object"爹梁。
在 ES 內(nèi)部,"對(duì)象" 被索引為一個(gè)扁平的鍵值對(duì)提澎。
curl -H "Content-Type: application/json" -XPOST localhost:9200/archive/person/1?pretty -d '
{
"region": "US",
"manager": {
"age": 30,
"name": {
"first": "John",
"last": "Smith"
}
}
}
默認(rèn)情況下姚垃,上述文檔類型被索引為以點(diǎn)號(hào)命名的數(shù)據(jù)結(jié)構(gòu),把層次結(jié)構(gòu)展開之后虱朵,數(shù)據(jù)結(jié)構(gòu)是由扁平的key/value對(duì)構(gòu)成:
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John",
"manager.name.last": "Smith"
}
2.2.2莉炉、數(shù)組
在 ElasticSearch 中钓账,沒有專門的數(shù)組(Array)數(shù)據(jù)類型,是開箱即用的(out of box)絮宁,不需要進(jìn)行任何配置梆暮,就可以直接使用。
在默認(rèn)情況下绍昂,任意一個(gè)字段都可以包含 0 或多個(gè)值啦粹,這意味著每個(gè)字段默認(rèn)都是數(shù)組類型,只不過窘游,數(shù)組類型的各個(gè)元素值的數(shù)據(jù)類型必須相同:
- 字符串?dāng)?shù)組: [ "one", "two" ]
- 整型數(shù)組: [ 1, 2 ]
- 數(shù)組數(shù)組: [ 1, [ 2, 3 ]] which is the equivalent of [ 1, 2, 3 ]
- 對(duì)象數(shù)組: [ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }]
注意:
- 動(dòng)態(tài)添加數(shù)據(jù)時(shí)唠椭,數(shù)組的第一個(gè)值的類型決定整個(gè)數(shù)組的類型
- 混合數(shù)組類型是不支持的,比如:[1,”abc”]
- 數(shù)組可以包含 null 值忍饰,空數(shù)組 [ ] 會(huì)被當(dāng)做 missing field 對(duì)待
對(duì)象數(shù)組贪嫂,在 ES 內(nèi)部將會(huì)被轉(zhuǎn)換為 "多值" 的扁平數(shù)據(jù)類型:
curl -H "Content-Type: application/json" -XPOST localhost:9200/lib/club/1?pretty -d '
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}'
# 在 es 內(nèi)部將轉(zhuǎn)為
{
"group": "fans",
"user.first": [
"alice",
"john"
],
"user.last": [
"smith",
"white"
]
}
這將導(dǎo)致每個(gè)數(shù)組元素(對(duì)象)內(nèi)部的字段關(guān)聯(lián)性丟失:
curl -H "Content-Type: application/json" -XGET localhost:9200/lib/club/_search?pretty -d '
{
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "John"
}
},
{
"match": {
"user.last": "White"
}
}
]
}
}
}'
字段 user.first 和 user.last 被展開成數(shù)組字段,但是艾蓝,這樣展開之后力崇,單個(gè)文檔內(nèi)部的字段之間的關(guān)聯(lián)就會(huì)丟失,在該例中赢织,展開的文檔數(shù)據(jù)丟失 first 和 last 字段之間的關(guān)聯(lián)亮靴,比如,Alice
和 white
的關(guān)聯(lián)就丟失了于置。
# 文檔被命中茧吊,顯然,John Smith 八毯、Alice White 兩組字段它們內(nèi)在的關(guān)聯(lián)性都丟失了
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "lib",
"_type" : "club",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
}
]
}
}
2.2.3搓侄、嵌套數(shù)據(jù)
嵌套數(shù)據(jù)類型是對(duì)象數(shù)據(jù)類型的特殊版本,它允許對(duì)象數(shù)組中的各個(gè)對(duì)象被索引宪彩,數(shù)組中的各個(gè)對(duì)象之間保持獨(dú)立休讳,能夠?qū)γ恳粋€(gè)文檔進(jìn)行單獨(dú)查詢。嵌套數(shù)據(jù)類型保留文檔的內(nèi)部之間的關(guān)聯(lián)尿孔。
ElasticSearch 引擎內(nèi)部使用不同的方式處理嵌套數(shù)據(jù)類型和對(duì)象數(shù)組的方式俊柔,對(duì)于嵌套數(shù)據(jù)類型,ElasticSearch 把數(shù)組中的每一個(gè)嵌套文檔(Nested Document)索引為單個(gè)文檔活合,這些文檔是隱藏(Hidden)的雏婶,文檔之間是相互獨(dú)立的,但是白指,保留文檔的內(nèi)部字段之間的關(guān)聯(lián)留晚,使用嵌套查詢(Nested Query)能夠獨(dú)立于其他文檔而去查詢單個(gè)文檔。
在創(chuàng)建嵌套數(shù)據(jù)類型的字段時(shí)告嘲,需要設(shè)置字段的type屬性為nested错维。
curl -H "Content-Type: application/json" -XPUT localhost:9200/my_index?pretty -d '
{
"mappings": {
"my_type": {
"properties": {
"group": {
"type": "keyword"
},
"user": {
"type": "nested",
"properties": {
"first": {
"type": "keyword"
},
"last": {
"type": "keyword"
}
}
}
}
}
}
}'
為嵌套字段賦予多個(gè)值奖地,ElasticSearch 自動(dòng)把字段值轉(zhuǎn)換為數(shù)組類型:
curl -H "Content-Type: application/json" -XPUT localhost:9200/my_index/my_type/1 -d '
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}'
在 ElasticSearch 內(nèi)部,嵌套的文檔(Nested Documents)被索引為很多獨(dú)立的隱藏文檔(separate documents)赋焕,這些隱藏文檔只能通過嵌套查詢(Nested Query)訪問参歹。每一個(gè)嵌套的文檔都是嵌套字段(文檔數(shù)組)的一個(gè)元素。嵌套文檔的內(nèi)部字段之間的關(guān)聯(lián)被 ElasticSearch 引擎保留隆判,而嵌套文檔之間是相互獨(dú)立的犬庇。
嵌套查詢用于查詢嵌套對(duì)象,執(zhí)行嵌套查詢執(zhí)行的條件是:嵌套對(duì)象被索引為單個(gè)文檔侨嘀,查詢作用在根文檔(Root Parent)上臭挽。嵌套查詢由關(guān)鍵字“nested”指定:
{
"nested": {
"path": "obj1",
"query": {...}
}
}
- path 參數(shù):指定嵌套字段的文檔路徑,根路徑是頂層的文檔咬腕,通過點(diǎn)號(hào)“.”來(lái)指定嵌套文檔的路徑欢峰;
- query 參數(shù):在匹配路徑(參數(shù) path)的嵌套文檔上執(zhí)行查詢,query參數(shù)指定對(duì)嵌套文檔執(zhí)行的查詢條件郎汪。
curl -H "Content-Type: application/json" -XGET localhost:9200/my_index/my_type/_search?pretty -d '
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "John"
}
},
{
"match": {
"user.last": "White"
}
}
]
}
}
}
}
}'
在該例中赤赊,ElasticSearch 引起保留 Alice 和 White 之間的關(guān)聯(lián),而 John 和 White 之間是沒有任何關(guān)聯(lián)的:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
2.3煞赢、地理位置類型(Geo datatypes)
地理位置信息類型用于存儲(chǔ)地理位置信息的經(jīng)緯度,地理坐標(biāo)點(diǎn)不能被動(dòng)態(tài)映射(dynamic mapping)自動(dòng)檢測(cè)哄孤,而是需要顯式聲明對(duì)應(yīng)字段類型為 geo_point
照筑。
curl -H "Content-Type: application/json" -XPUT localhost:9200/my_index1?pretty -d '
{
"mappings": {
"my_type1": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}'
location
被聲明為 geo_point
后,就可以索引包含了經(jīng)緯度信息的文檔了瘦陈。經(jīng)緯度信息的形式可以是字符串凝危,數(shù)組或者對(duì)象。
# 明確以 lat 和 lon 作為屬性的對(duì)象晨逝;
curl -H "Content-Type: application/json" -XPUT localhost:9200/my_index1/my_type1/1?pretty -d '
{
"text": "Geo-point as an object",
"location": {
"lat": 41.12,
"lon": -71.34
}
}'
# 以半角逗號(hào)分割的字符串形式 "lat,lon"
curl -H "Content-Type: application/json" -XPUT localhost:9200/my_index1/my_type1/2?pretty -d '
{
"text": "Geo-point as a string",
"location": "41.12,-71.34"
}'
curl -H "Content-Type: application/json" -XPUT localhost:9200/my_index1/my_type1/3?pretty -d '
{
"text": "Geo-point as a geohash",
"location": "drm3btev3e86"
}'
# 數(shù)組形式表示 [lon,lat]
curl -H "Content-Type: application/json" -XPUT localhost:9200/my_index1/my_type1/4?pretty -d '
{
"text": "Geo-point as an array",
"location": [
-71.34,
41.12
]
}'
有四種地理坐標(biāo)點(diǎn)相關(guān)的過濾方式可以用來(lái)選中或者排除文檔:
-
geo_bounding_box
::找出落在指定矩形框中的坐標(biāo)點(diǎn)
-
geo_distance
::找出與指定位置在給定距離內(nèi)的點(diǎn)
-
geo_distance_range
::找出與指定點(diǎn)距離在給定最小距離和最大距離之間的點(diǎn)
-
geo_polygon
::找出落在多邊形中的點(diǎn)蛾默。這個(gè)過濾器使用代價(jià)很大。
curl -H "Content-Type: application/json" -XGET localhost:9200/my_index1/my_type1/_search?pretty -d '
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 42,
"lon": -72
},
"bottom_right": {
"lat": 40,
"lon": -70
}
}
}
}
}'
2.4捉貌、特定類型(Specialised datatypes)
IPv4 類型(IPv4 datatype):ip 用于IPv4 地址
Completion 類型(Completion datatype):completion 提供自動(dòng)補(bǔ)全建議
Token count 類型(Token count datatype):token_count 用于統(tǒng)計(jì)做子標(biāo)記的字段的index數(shù)目支鸡,該值會(huì)一直增加,不會(huì)因?yàn)檫^濾條件而減少
mapper-murmur3 類型:通過插件趁窃,可以通過 _murmur3_
來(lái)計(jì)算 index 的哈希值
附加類型(Attachment datatype):采用 mapper-attachments 插件牧挣,可支持_attachments_
索引,例如 Microsoft office 格式醒陆,Open Documnet 格式瀑构, ePub,HTML 等
三刨摩、映射 parameters
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-params.html#mapping-params
analyzer
分詞器寺晌,如果修改分詞器世吨,要重建索引,因?yàn)榉衷~的內(nèi)容是放到倒排索引中的呻征,如果不重建索引另假,是無(wú)法修改倒排索引中內(nèi)容的,所以選擇分詞器就比較重要怕犁,比如中文分詞使用 ik_smart 還是 ik_max_word边篮。
normalizer
用于解析前的標(biāo)準(zhǔn)化配置,比如把所有的字符轉(zhuǎn)化為小寫奏甫。
index
index 選項(xiàng)控制是否索引字段值戈轿。 它接受 true 或 false,默認(rèn)為 true阵子。 未編制索引的字段不可查詢思杯。
null_value
無(wú)法索引或搜索空值 null。 當(dāng)字段設(shè)置為 null(或空數(shù)組或空值數(shù)組)時(shí)挠进,它被視為該字段沒有值色乾。
null_value 參數(shù)允許使用指定的值替換顯式空值,以便可以對(duì)其進(jìn)行索引和搜索领突。
四暖璧、參考資料
1.ES 權(quán)威指南
2.https://blog.csdn.net/zx711166/article/details/81667862
3.https://blog.csdn.net/ZYC88888/article/details/83059040