來源:https://mp.weixin.qq.com/s/4h95pWhWSGBRGgR0_rD_Dg
映射簡(jiǎn)介及類比
映射也就是mapping更舞,用來定義一個(gè)文檔以及其所包含的字段如何被存儲(chǔ)和索引,可以在映射中事先定義字段的數(shù)據(jù)類型把夸、分詞等屬性铁孵。
與關(guān)系型數(shù)據(jù)庫對(duì)比
在關(guān)系型數(shù)據(jù)庫中創(chuàng)建數(shù)據(jù)表時(shí)會(huì)設(shè)置字段的類型豹储,如下?創(chuàng)建user_info表汇竭,
create?table?user_info
(
??id?????????VARCHAR2(32) not?null,
??name???????VARCHAR2(50),
??tel ???????VARCHAR2(11),
??create_time DATE
)
es創(chuàng)建索引時(shí)同樣可以設(shè)置字段的屬性,作用是使索引的配置更加靈活和完善圃验,可以在mapping中設(shè)置字段的類型掉伏、字段的權(quán)重等信息。????
字段類型
上面我把常用mapping類型標(biāo)紅了。
字符串類型
(1)string
string類型在ElasticSearch?舊版本中使用較多斧散,從ElasticSearch 5.x開始不再支持string供常,由text和keyword類型替代。
(2)text
? ? 當(dāng)一個(gè)字段是要被全文搜索的颅湘,比如Email內(nèi)容话侧、產(chǎn)品描述,應(yīng)該使用text類型闯参。設(shè)置text類型以后,字段內(nèi)容會(huì)被分析悲立,在生成倒排索引以前鹿寨,字符串會(huì)被分析器分成一個(gè)一個(gè)詞項(xiàng)。text類型的字段不用于排序薪夕,很少用于聚合脚草。
(3)keyword
keyword類型適用于索引結(jié)構(gòu)化的字段,比如email地址原献、主機(jī)名馏慨、狀態(tài)碼和標(biāo)簽。如果字段需要進(jìn)行過濾(比如查找已發(fā)布博客中status屬性為published的文章)姑隅、排序写隶、聚合。keyword類型的字段只能通過精確值搜索到讲仰。
整數(shù)類型
類型取值范圍
byte-128~127
short-32768~32767
integer-231~231-1
long-263~263-1
? ?在滿足需求的情況下慕趴,盡可能選擇范圍小的數(shù)據(jù)類型。比如鄙陡,某個(gè)字段的取值最大值不會(huì)超過100冕房,那么選擇byte類型即可。迄今為止吉尼斯記錄的人類的年齡的最大值為134歲趁矾,對(duì)于年齡字段耙册,short足矣。字段的長度越短毫捣,索引和搜索的效率越高详拙。
浮點(diǎn)類型
類型取值范圍
doule64位雙精度IEEE 754浮點(diǎn)類型
float32位單精度IEEE 754浮點(diǎn)類型
half_float16位半精度IEEE 754浮點(diǎn)類型
scaled_float縮放類型的的浮點(diǎn)數(shù)
? ? 對(duì)于float、half_float和scaled_float,-0.0和+0.0是不同的值培漏,使用term查詢查找-0.0不會(huì)匹配+0.0溪厘,同樣range查詢中上邊界是-0.0不會(huì)匹配+0.0,下邊界是+0.0不會(huì)匹配-0.0牌柄。其中scaled_float畸悬,比如價(jià)格只需要精確到分,price為57.34的字段縮放因子為100,存起來就是5734優(yōu)先考慮使用帶縮放因子的scaled_float浮點(diǎn)類型蹋宦。
date類型
我們?nèi)祟愂褂玫挠?jì)時(shí)系統(tǒng)是相當(dāng)復(fù)雜的:秒是基本單位, 60秒為1分鐘, 60分鐘為1小時(shí), 24小時(shí)是一天……如果計(jì)算機(jī)也使用相同的方式來計(jì)時(shí),?那顯然就要用多個(gè)變量來分別存放年月日時(shí)分秒,?不停的進(jìn)行進(jìn)位運(yùn)算,?而且還要處理偶爾的閏年和閏秒以及協(xié)調(diào)不同的時(shí)區(qū).?基于”追求簡(jiǎn)單”的設(shè)計(jì)理念, UNIX在內(nèi)部采用了一種最簡(jiǎn)單的計(jì)時(shí)方式:
日期類型表示格式可以是以下幾種:
(1)日期格式的字符串披粟,比如 “2018-01-13” 或 “2018-01-13 12:10:30”
(2)long類型的毫秒數(shù)( milliseconds-since-the-epoch,epoch就是指UNIX誕生的UTC時(shí)間1970年1月1日0時(shí)0分0秒)
(3)integer的秒數(shù)(seconds-since-the-epoch)
ElasticSearch?內(nèi)部會(huì)將日期數(shù)據(jù)轉(zhuǎn)換為UTC冷冗,并存儲(chǔ)為milliseconds-since-the-epoch的long型整數(shù)守屉。
boolean類型
邏輯類型(布爾類型)可以接受true/false/”true”/”false”值
(1)先刪除已經(jīng)存在的索引,再創(chuàng)建
DELETE test
PUT test
{
??"mappings":{
????"my":{
??????"properties": {
????????"empty":{"type":"boolean"}
??????}
????}
??}
}
?binary類型
二進(jìn)制字段是指用base64來表示索引中存儲(chǔ)的二進(jìn)制數(shù)據(jù)蒿辙,可用來存儲(chǔ)二進(jìn)制形式的數(shù)據(jù)拇泛,例如圖像。默認(rèn)情況下思灌,該類型的字段只存儲(chǔ)不索引俺叭。二進(jìn)制類型只支持index_name屬性。
array類型
在ElasticSearch中泰偿,沒有專門的數(shù)組(Array)數(shù)據(jù)類型熄守,但是,在默認(rèn)情況下耗跛,任意一個(gè)字段都可以包含0或多個(gè)值裕照,這意味著每個(gè)字段默認(rèn)都是數(shù)組類型,只不過调塌,數(shù)組類型的各個(gè)元素值的數(shù)據(jù)類型必須相同晋南。在ElasticSearch中,數(shù)組是開箱即用的(out of box)烟阐,不需要進(jìn)行任何配置搬俊,就可以直接使用。
在同一個(gè)數(shù)組中蜒茄,數(shù)組元素的數(shù)據(jù)類型是相同的唉擂,ElasticSearch不支持元素為多個(gè)數(shù)據(jù)類型:[ 10,?“some string”?],常用的數(shù)組類型是:
(1)字符數(shù)組: [?“one”,?“two”?]
(2)整數(shù)數(shù)組: productid:[ 1, 2 ]
(3)對(duì)象(文檔)數(shù)組:?“user”:[ {?“name”:?“Mary”,?“age”: 12 }, {?“name”:?“John”,?“age”: 10 }]檀葛,ElasticSearch內(nèi)部把對(duì)象數(shù)組展開為?{“user.name”: [“Mary”,?“John”],?“user.age”: [12,10]}
object類型
JSON天生具有層級(jí)關(guān)系玩祟,文檔會(huì)包含嵌套的對(duì)象,obejct類型會(huì)使得內(nèi)部對(duì)象的關(guān)聯(lián)性丟失插入:對(duì)象數(shù)據(jù)"user": [{?"first":?"John",?"last":"Smith"},{?"first":"Alice","last":"White"}]轉(zhuǎn)換后{"user.first":"alice","john"],"user.last":["smith",?"white"]}
PUT test/my/1
{
??"employee":{
????"age":30,
????"fullname":{
??????"first":"hadron",
??????"last":"cheng"
????}
??}
}
上面文檔整體是一個(gè)JSON屿聋,JSON中包含一個(gè)employee,employee又包含一個(gè)fullname空扎。
GET test/_mapping
{
??"test": {
????"mappings": {
??????"my": {
????????"properties": {
??????????"employee": {
????????????"properties": {
??????????????"age": { "type": "long"},
??????????????"fullname": {
????????????????"properties": {
??????????????????"first": {
????????????????????"type": "text",
????????????????????"fields": {
??????????????????????"keyword": {
????????????????????????"type": "keyword",
????????????????????????"ignore_above": 256
??????????????????????}
????????????????????}
??????????????????},
??????????????????"last": {
????????????????????"type": "text",
????????????????????"fields": {
??????????????????????"keyword": {
????????????????????????"type": "keyword",
????????????????????????"ignore_above": 256
??????????????????????}
????????????????????}
??????????????????}
????????????????}
??????????????}
????????????}
??????????}
????????}
??????}
????}
??}
}
ip類型
ip類型的字段用于存儲(chǔ)IPv4或者IPv6的地址
(1)創(chuàng)建索引
DELETE test
PUT test
{
??"mappings": {
????"my":{
??????"properties": {
????????"nodeIP":{
??????????"type": "ip"
????????}
??????}
????}
??}
}
查詢字段
GET test/_search
{
??"query": {
????"term": {
??????"nodeIP": "192.168.0.0/16"
????}
??}
}
?{
??"took": 111,
??"timed_out": false,
??"_shards": {
????"total": 5,
????"successful": 5,
????"skipped": 0,
????"failed": 0
??},
??"hits": {
????"total": 1,
????"max_score": 1,
????"hits": [
??????{
????????"_index": "test",
????????"_type": "my",
????????"_id": "1",
????????"_score": 1,
????????"_source": {
??????????"nodeIP": "192.168.1.2"
????????}
??????}
????]
??}
}
nested類型
nested類型就是為了解決object類型在對(duì)象數(shù)組上丟失關(guān)聯(lián)性的問題的,如果將字段設(shè)置為nested類型润讥,那個(gè)每一個(gè)嵌套對(duì)象都會(huì)被索引為一個(gè)?"隱藏的獨(dú)立文檔"
在Elasticsearch實(shí)戰(zhàn)場(chǎng)景中转锈,我們或多或少會(huì)遇到嵌套文檔的組合形式
2)Nested嵌套類型
定義index mapping
PUT /my_index
{
????"mappings": {
????????"_doc" : {
????????????"properties" : {
????????????????"obj1" : {
????????????????????"type" : "nested"
????????????????}
????????????}
????????}
????}
}
join類型
1)父子文檔
父子文檔在5.X版本中通過parent-child父子type實(shí)現(xiàn),即:1個(gè)索引對(duì)應(yīng)多個(gè)type楚殿;
6.X+版本已經(jīng)不再支持一個(gè)索引多個(gè)type撮慨,6.X+的父子索引的實(shí)現(xiàn)改成Join。
靜態(tài)映射
? ? ?靜態(tài)映射是在創(chuàng)建索引時(shí)手工指定索引映射(即索引字段的類型),這個(gè)類似關(guān)系型數(shù)據(jù)庫創(chuàng)建表指定字段類型砌溺。相比動(dòng)態(tài)映射影涉,靜態(tài)映射可以更加詳細(xì)、準(zhǔn)確的配置信息规伐。
創(chuàng)建mapping
PUT user_info
{
? "mappings": {
? ? "dynamic": false,
? ? "properties": {
? ? ? "title": {
? ? ? ? "type": "text",
? ? ? ? "analyzer": "ik_max_word",
? ? ? ? "search_analyzer": "ik_max_word"
? ? ? },
? ? ? "name": {
? ? ? ? "type": "keyword",
? ? ? ? "index": "true"
? ? ? },
? ? ? "address": {
? ? ? ? "type": "keyword",
? ? ? ? "index": "false"
? ? ? },
? ? ? "userIp": {
? ? ? ? "type": "ip"
? ? ? },
? ? ? "position ": {?
? ? ? ? ? "type" : "geo_point"
? ? ? },
? ? ? "china": {
? ? ? ? "type": "boolean"
? ? ? },
? ? ? "birthdate": {
? ? ? ? "type": "date",
? ? ? ? "format": "yyyy-MM-dd"
? ? ? }
? ? }
? }
}
我們看到右側(cè)執(zhí)行成功蟹倾,如果出現(xiàn)"reason": "failed to find global analyzer [ik_max_word]" 檢查ik分詞插件是否裝好。最后覺得有用點(diǎn)擊個(gè)在看猖闪。