第3章 映射
映射是定義存儲(chǔ)和索引的文檔類型以及字段的過程幢哨。索引中的每一個(gè)文檔都有一個(gè)類型题诵,每種類型都有它自己的映射懂酱。一個(gè)映射定義了文檔結(jié)構(gòu)內(nèi)每個(gè)字段的數(shù)據(jù)類型各墨。映射通過配置來定義字段類型與該類型相關(guān)聯(lián)的元數(shù)據(jù)的關(guān)系逛裤。例如瘩绒,可以通過映射來定義日期類型的格式、數(shù)字類型的格式或者文檔中所有字段的值是否應(yīng)該被_all字段索引等带族。本章將介紹映射的概念锁荔、參數(shù),以及動(dòng)態(tài)映射的使用等蝙砌。
3.1 概念
1.映射類型
每個(gè)索引擁有一個(gè)或多個(gè)映射類型阳堕,用來在索引中將文檔劃分為不同的邏輯組。
每個(gè)映射類型擁有:
- 元字段:用來定義如何處理文檔的元數(shù)據(jù)择克。元字段包括文檔的_index字段恬总、_type字段、_id字段和_source字段肚邢。
- 字段或?qū)傩裕好總€(gè)映射類型包含與類型相關(guān)的字段或?qū)傩粤斜硪佳摺M凰饕胁煌挠成漕愋偷南嗤Q字段必須擁有相同的映射拭卿。
2. 字段數(shù)據(jù)類型
每個(gè)字段擁有一個(gè)數(shù)據(jù)類型,可以是簡單數(shù)據(jù)類型贱纠,比如字符串型(String)峻厚、日期型(date)、長整型(long)谆焊、雙精度浮點(diǎn)型(double)惠桃、布爾型(boolean)或者IP。
支持JSON的層次性類型懊渡,比如對(duì)象(object)刽射、嵌套(nested),或者特定的類型剃执,比如地理點(diǎn)(geo_point)誓禁、地理形狀(geo_shape)。
基于不同目的對(duì)同一個(gè)字段進(jìn)行不同方式的索引是很有用的肾档。例如摹恰,一個(gè)字符串類型字段可以在全文搜索中作為分析字段,在排序或聚合時(shí)作為不分析的字段怒见∷状龋或者,可以通過標(biāo)準(zhǔn)分析器遣耍、英文分析器或者法語分析器對(duì)字符串字段進(jìn)行索引闺阱。
3. 動(dòng)態(tài)映射
字段和映射類型在使用前不需要事先定義。依靠動(dòng)態(tài)映射舵变,通過索引文檔酣溃,新的映射類型和字段名會(huì)自動(dòng)添加。新的字段可以添加到頂級(jí)映射類型或者映射內(nèi)部的對(duì)象和嵌入字段纪隙。
動(dòng)態(tài)映射可以配置自定義映射用于新類型或者新字段赊豌。
4. 顯式映射
相對(duì)于Elasticsearch來說,我們對(duì)于數(shù)據(jù)類型的掌控更加全面绵咱,所以我們可以制定顯式映射而不是使用動(dòng)態(tài)映射碘饼。
當(dāng)創(chuàng)建索引的時(shí)候,可以創(chuàng)建映射類型和字段悲伶。也可以在當(dāng)前的索引中通過映射創(chuàng)建接口添加映射類型和字段艾恼。
5. 更新當(dāng)前映射
除了記錄之外悴了,現(xiàn)有的映射類型和字段不能更新茵肃。修改映射意味著廢棄已經(jīng)索引的文檔,我們反而應(yīng)該根據(jù)映射創(chuàng)建新的索引并且重新索引數(shù)據(jù)虎囚。
6. 映射類型之間共享字段
映射類型在每個(gè)索引中是唯一的淮椰,就是在一個(gè)索引的多個(gè)類型中五慈,如果多個(gè)類型中的映射名稱一樣纳寂,則它必須是相同的類型。
例如:如果一個(gè)title字段同時(shí)存在于user和blogpost映射類型中泻拦,title字段在每個(gè)類型中必須擁有相同的映射毙芜。這個(gè)規(guī)則的唯一例外是:對(duì)于copy_to參數(shù)、dynamic參數(shù)争拐、enabled參數(shù)腋粥、ignore_above參數(shù),include_in_all參數(shù)架曹,每個(gè)不同映射類型中的字段擁有不同的參數(shù)設(shè)置隘冲。
通常,相同名稱的字段由相同類型的數(shù)據(jù)構(gòu)成绑雄,所以擁有相同的索引是沒有問題的展辞。當(dāng)產(chǎn)生類型沖突的時(shí)候,可以選擇更詳細(xì)的命名万牺,比如user_title和blog_title罗珍。
7. 映射示例
當(dāng)創(chuàng)建索引的時(shí)候,可以指定映射:
請(qǐng)求:
PUT http://127.0.0.1:9200/secisland
{
"mappings":{
"user":{
"_all":{"enabled": false},
"properties": {
"title": {"type": "string"},
"name": {"type": "string"},
"age": {"type":"integer"}
}
},
"blogpost": {
"properties":{
"title": {"type": "string"},
"body": {"type": "string"},
"user_id": {"type":"string", "index":"not_analyzed"},
"created": {
"type":"date",
"format" : "strict_date_optional_time||epoch_millis"
}
}
}
}
}
上面的接口表示創(chuàng)建一個(gè)名為secisland的索引脚粟,在索引中添加名為user和blogpost的映射類型覆旱。user映射類型取消元字段_all,指定了每個(gè)映射類型的字段或?qū)傩院宋蓿付嗣總€(gè)字段的數(shù)據(jù)類型和映射扣唱。
3.2 字段數(shù)據(jù)類型
Elasticsearch支持一系列不同的數(shù)據(jù)類型來定義文檔字段,分為核心數(shù)據(jù)团南、復(fù)雜數(shù)據(jù)画舌、地理數(shù)據(jù)、專門數(shù)據(jù)類型已慢。
核心數(shù)據(jù)類型包括:
- 字符串?dāng)?shù)據(jù)類型:string
- 數(shù)字型數(shù)據(jù)類型:long、integer霹购、short佑惠、byte、double齐疙、float
- 日期型數(shù)據(jù)類型:date
- 布爾型數(shù)據(jù)類型:boolean
- 二進(jìn)制數(shù)據(jù)類型:binary
復(fù)雜數(shù)據(jù)類型包括:
- 數(shù)組數(shù)據(jù)類型:不需要專門的類型來定義數(shù)組膜楷。
- 對(duì)象數(shù)據(jù)類型:object,單獨(dú)的JSON對(duì)象贞奋。
- 嵌套數(shù)據(jù)類型:nested赌厅,關(guān)于JSON對(duì)象的數(shù)組。
地理數(shù)據(jù)類型包括:
- 地理點(diǎn)數(shù)據(jù)類型:geo_point轿塔,經(jīng)緯點(diǎn)特愿。
- 地理形狀數(shù)據(jù)類型:geo_shape仲墨,多邊形的復(fù)雜地理形狀。
專門數(shù)據(jù)類型包括:
- IPv4數(shù)據(jù)類型:IP協(xié)議為IPv4的地址揍障。
- 完成數(shù)據(jù)類型:completion目养,提供自動(dòng)補(bǔ)全的建議。
- 單詞計(jì)數(shù)數(shù)據(jù)類型:token_count毒嫡,統(tǒng)計(jì)字符串中的單詞數(shù)量癌蚁。
3.2.1 核心數(shù)據(jù)類型
1. 字符串?dāng)?shù)據(jù)類型
字符串?dāng)?shù)據(jù)類型的字段接受文本值,可以分為如下兩種:
- 全文本兜畸。全文本值通常用于基于文本的相關(guān)性搜索努释,全文本字段可以分詞,即在索引執(zhí)行之前通過一個(gè)分詞器將字符串轉(zhuǎn)換為單詞列表咬摇。分詞操作使得Elasticsearch可以在全文本字段上搜索單詞伐蒂。全文本字段不用于排序而且很少用于聚合。
- 關(guān)鍵字菲嘴。關(guān)鍵字是個(gè)精準(zhǔn)值饿自。通常用于過濾(例如,為published的博客文章獲取所有status字段值)龄坪、排序昭雌、參與聚合。關(guān)鍵字字段不參與分詞健田。
全文本(可以分詞)字段和關(guān)鍵字(不可以分詞)字段映射示例如下:
請(qǐng)求:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"full_name": {
"type": "string"
},
"status": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
其中烛卧,full_name字段是一個(gè)可分詞的全文本類型字段——index:默認(rèn)是analyzed。status字段是一個(gè)不可分詞的關(guān)鍵字字段妓局。
同一個(gè)字段同時(shí)擁有全文本和關(guān)鍵字兩個(gè)版本总放,通常是很有用的:一個(gè)用于全文搜索,另一個(gè)用于聚合和排序好爬。這可以通過多字段來實(shí)現(xiàn)局雄。
字符串?dāng)?shù)據(jù)類型的字段可以接受的參數(shù)如表3-1所示。
表3-1 字符串?dāng)?shù)據(jù)類型的字段可以接受的參數(shù)
參數(shù) | 說明 |
---|---|
analyzer | 分詞器可以用于可分詞的字符串型字段存炮。默認(rèn)為默認(rèn)的索引分詞器或者標(biāo)準(zhǔn)分詞器 |
boost | 字段級(jí)索引加權(quán)炬搭。接受浮點(diǎn)型數(shù)字,默認(rèn)值是1.0 |
doc_values | 定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上穆桂,以便用于排序宫盔、聚合或者腳本。接受true或false參數(shù)享完。對(duì)于不可分詞字段灼芭,默認(rèn)值是true“阌郑可分詞字段不支持這個(gè)參數(shù) |
fielddate | 決定字段是否可以使用內(nèi)存字段值進(jìn)行排序彼绷,聚合或者在腳本中使用巍佑。接受disabled或者paged_bytes(默認(rèn))參數(shù)。沒有分析過的字段會(huì)優(yōu)先使用文檔值 |
ignore_above | 不要索引或執(zhí)行任何長于這個(gè)值的字符串苛预。默認(rèn)為0(禁用) |
include_in_all | 決定字段是否應(yīng)該包含在_all字段中句狼。接受true或false參數(shù) |
index | 決定字段是否可以被用戶搜索。接受參數(shù)analyzed(默認(rèn)热某,視為全文本字段)腻菇,not_analyzed(作為關(guān)鍵字字段)以及no |
index_options | 定義存儲(chǔ)在索引中,用于搜索和突出用途的信息 |
norms | 計(jì)算查詢得分的時(shí)候是否應(yīng)該考慮字段長度昔馋。默認(rèn)依賴于索引設(shè)置:analyzed字段默認(rèn)為{"enabled":true, "loading":"lazy"}筹吐。not_analyzed字段默認(rèn)為{"enabled":false} |
null_value | 接受一個(gè)字符串值替換所有null值。默認(rèn)為null秘遏,意味著字段作為缺失字段丘薛。如果字段是可分詞(analyzed)的,null_value也會(huì)被分詞 |
position_increment_gap | 定義字符串?dāng)?shù)組中應(yīng)該插入的虛擬索引詞的數(shù)量邦危。默認(rèn)值為100洋侨,以一個(gè)較合理的值來阻止短語查詢?cè)诳缱侄纹ヅ渌饕~的時(shí)候溢出 |
store | 決定字段值是否應(yīng)該被存儲(chǔ)以及從_source字段分別獲取。接受參數(shù)true或false(默認(rèn)) |
search_analyzer | 指定搜索時(shí)用在可分詞字段上的分詞器 |
search_quote_analyzer | 指定搜索短語時(shí)使用的分詞器 |
similarity | 指定使用的相似度評(píng)分算法倦蚪,默認(rèn)為TF/IDF |
term_vector | 定義一個(gè)可分詞字段是否應(yīng)該存儲(chǔ)索引詞向量希坚。默認(rèn)為no |
2. 數(shù)字型數(shù)據(jù)類型
數(shù)字型數(shù)據(jù)類型支持的數(shù)字類型如表3-2所示。
表3-2 數(shù)字型數(shù)據(jù)類型
參數(shù) | 說明 |
---|---|
long | 一個(gè)有符號(hào)的64位整數(shù)陵且,最小值為-263裁僧,最大值為263-1 |
integer | 一個(gè)有符號(hào)的32位整數(shù),最小值為-231慕购,最大值為231-1 |
short | 一個(gè)有符號(hào)的16位整數(shù)聊疲,最小值為-32768,最大值為32767 |
byte | 一個(gè)有符號(hào)的8位整數(shù)沪悲,最小值為-128获洲,最大值為127 |
double | 64位雙精度浮點(diǎn)數(shù) |
float | 32位單精度浮點(diǎn)數(shù) |
數(shù)字型字段映射配置示例如下:
請(qǐng)求:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog:" {
"properties": {
"number_of_bytes": {
"type": "integer"
},
"time_in_seconds": {
"type": "float"
}
}
}
}
}
數(shù)字型字段參數(shù)見表3-3。
表3-3數(shù)字型字段參數(shù)
參數(shù) | 說明 |
---|---|
coerce | 試著將字符串型數(shù)據(jù)轉(zhuǎn)換為整數(shù)型數(shù)字?jǐn)?shù)據(jù) |
boost | 字段級(jí)索引加權(quán)殿如,接受浮點(diǎn)型數(shù)字參數(shù)昌妹,默認(rèn)為1.0 |
doc_values | 定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上,以便用于排序握截、聚合或者腳本。接受true(默認(rèn))或false參數(shù) |
ignore_malformed | 如果是true烂叔,畸形的數(shù)字會(huì)被忽略谨胞。如果是false(默認(rèn)),畸形數(shù)字會(huì)拋出異常并丟棄整個(gè)文檔 |
include_in_all | 決定 字段是否應(yīng)該包含在_all字段中蒜鸡。接受true或false參數(shù)胯努。如果所有被設(shè)置在no或者父對(duì)象字段設(shè)置include_in_all為false牢裳,參數(shù)默認(rèn)值為false;其他情況下叶沛,默認(rèn)值為true |
index | 決定字段是否可以被用戶搜索蒲讯。接受參數(shù)not_analyzed(默認(rèn))以及no |
null_value | 接受與字段同類型的數(shù)字型值來代替null值。默認(rèn)是null灰署,意味著字段作為缺失字段 |
precision_step | 控制索引的額外索引詞的數(shù)量來使范圍查詢更快速判帮。默認(rèn)值取決于數(shù)字類型 |
store | 決定字段值是否應(yīng)該存儲(chǔ)以及從_source字段分別獲取。接受參數(shù)true或false(默認(rèn)) |
3. 日期型數(shù)據(jù)類型
JSON沒有日期型數(shù)據(jù)類型溉箕,所以在Elasticsearch中晦墙,日期可以是:
- 包含格式化日期的字符串,例如“2015-01-01”或者“2015/01/01 12:10:30”肴茄。
- 代表世界毫秒數(shù)的長整型數(shù)字晌畅。
- 代表時(shí)間秒數(shù)的整數(shù)。
通常寡痰,日期被轉(zhuǎn)換為UTC(如果時(shí)區(qū)被指定)但是存儲(chǔ)為代表時(shí)間毫秒數(shù)的長整數(shù)抗楔。
可以自定義時(shí)間格式,如果沒有指定格式拦坠,則使用默認(rèn)值:
strict_date_optional_time||epoch_millis
這意味著接受任意時(shí)間戳的日期值连躏,例如:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"date": {
"type":"date"
}
}
}
}
}
創(chuàng)建映射之后,可以防止日期型數(shù)據(jù):
PUT http://127.0.0.1:9200/secisland/secilog/1
{"date":"2015-01-01"}
PUT http://127.0.0.1:9200/secisland/secilog/2
{"date":"2015-01-01T12:10:30Z"}
PUT http://127.0.0.1:9200/secisland/secilog/3
{"date":"1420070400001"}
(1)多日期格式
使用雙豎線(||)分割贪婉,可以指定多個(gè)日期格式反粥。每個(gè)格式會(huì)被依次嘗試,直到找到匹配的格式疲迂。第一個(gè)格式會(huì)用于將時(shí)間毫秒數(shù)值轉(zhuǎn)換為字符串:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"date": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
(2)日期型數(shù)字的字段參數(shù)
日期型數(shù)據(jù)的字段參數(shù)參見表3-4才顿。
表3-4 日期型字段參數(shù)
參數(shù) | 說明 |
---|---|
boost | 字段級(jí)索引加權(quán),接受浮點(diǎn)型數(shù)字參數(shù)尤蒿,默認(rèn)為1.0 |
doc_values | 定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上郑气,以便用于排序,聚合或者腳本腰池。接受true(默認(rèn))或false參數(shù) |
format | 可解析的日期格式尾组。默認(rèn)為strict_date_optional_time||epoch_millis |
ignore_malformed | 如果是true,畸形的日期會(huì)被忽略示弓。如果是false(默認(rèn))讳侨,畸形日期會(huì)拋出異常并丟棄整個(gè)文檔 |
include_in_all | 決定字段是否應(yīng)該包含在_all字段中。接受true或false參數(shù)奏属。如果索引被設(shè)置為no或者父對(duì)象字段設(shè)置include_in_all為false跨跨,參數(shù)默認(rèn)值為false;其他情況下,默認(rèn)值為true |
index | 決定字段是否可以被用戶搜索勇婴。接受參數(shù)not_analyzed(默認(rèn))以及no |
null_value | 接受日期型值來代替null值忱嘹。默認(rèn)是null,意味著字段作為缺失字段耕渴。 |
precision_step | 控制索引的額外索引詞的數(shù)量來使范圍查詢更快速拘悦。默認(rèn)值為16 |
store | 決定字段值是否應(yīng)該存儲(chǔ)以及從_source字段分別獲取。接受參數(shù)true或false(默認(rèn)) |
4. 布爾數(shù)據(jù)類型
布爾型字段接受true或false值橱脸,也可以接受代表真或假的字符串和數(shù)字:
- 假值——false础米,“false”,“off”慰技,“no”椭盏,“0”,“”(空字符串)吻商,0掏颊,0.0。
- 真值——其他任何非假的值艾帐。
示例如下:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"is_published": {
"type": "boolean"
}
}
}
}
}
請(qǐng)求:
POST http://127.0.0.1:9200/secisland/secilog/1
{"is_published": true}
索引詞聚合之類的聚合使用1和0作為key乌叶,使用字符串"true"和"false"作為key_as_string。使用腳本時(shí)柒爸,布爾字段返回1和0准浴。布爾型字段參數(shù)見表3-5。
表3-5 布爾型字段參數(shù)
參數(shù) | 說明 |
---|---|
boost | 字段級(jí)索引加權(quán)捎稚,接受浮點(diǎn)型數(shù)字參數(shù)乐横,默認(rèn)為1.0 |
doc_values | 定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上,以便用于排序今野、聚合或者腳本葡公。接受true(默認(rèn))或false參數(shù) |
index | 決定字段是否可以被用戶搜索。接受參數(shù)not_analyzed(默認(rèn))以及no |
null_value | 接受布爾型值來代替null值条霜。默認(rèn)是null催什,意味著字段被作為缺失字段 |
store | 決定字段值是否應(yīng)該被存儲(chǔ)以及從_source字段分別獲取。接受參數(shù)true或false(默認(rèn)) |
5. 二進(jìn)制數(shù)據(jù)類型
二進(jìn)制數(shù)據(jù)類型接受Base64編碼字符串的二進(jìn)制值宰睡。字段不以默認(rèn)方式存儲(chǔ)而且不能搜索:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"name": {"type":"string"},
"blob": {"type":"binary"}
}
}
}
}
PUT http://127.0.0.1:9200/secisland/secilog/1
{
"name": "Some binary blob",
"blob": "U29tZSBiaW5hcnkgYmxvYg=="
}
Base64編碼二進(jìn)制值不能嵌入換行符\n蒲凶。二進(jìn)制數(shù)據(jù)類型的字段參數(shù)如下所示:
- doc_values——定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上,以便用于排序拆内、聚合或者腳本旋圆。接受true(默認(rèn))或false參數(shù)。
- store——決定字段值是否應(yīng)該存儲(chǔ)以及從_source字段分別獲取麸恍。接受參數(shù)true或false(默認(rèn))灵巧。
3.2.2 復(fù)雜數(shù)據(jù)類型
1. 數(shù)組數(shù)據(jù)類型
在Elasticsearch中,沒有專門的數(shù)組類型。每個(gè)字段默認(rèn)可以包含零個(gè)或更多的值孩等,然而,數(shù)組中所有的值都必須是相同的數(shù)據(jù)類型采够。例如:
- 字符串?dāng)?shù)組:["one", "two"]
- 整數(shù)數(shù)組:[1,2]
- 由數(shù)組組成的數(shù)組:[1,[2,3]]肄方,等同于[1,2,3]
- 對(duì)象數(shù)組:[{"name":"Mary","age":12}, {"name":"John", "age":10}]
注意:無法對(duì)數(shù)組中的每一個(gè)對(duì)象進(jìn)行單獨(dú)的查詢。
當(dāng)動(dòng)態(tài)添加字段的時(shí)候蹬癌,數(shù)組中第一個(gè)元素的值決定了字段類型权她,隨后的所有值必須是相同的數(shù)據(jù)類型或者可以強(qiáng)制轉(zhuǎn)換為相同的數(shù)據(jù)類型。
Elasticsearch不支持混合數(shù)據(jù)類型的數(shù)組逝薪,比如:[10, "some string"]隅要。
數(shù)組可能包含null值,會(huì)被null_value配置替換掉或者忽略掉董济。一個(gè)空數(shù)組[]被當(dāng)做缺失字段——沒有值的字段步清。
2. 對(duì)象數(shù)據(jù)類型
JSON文檔是天然分層的:文檔可以包含內(nèi)部對(duì)象。同樣虏肾,內(nèi)部對(duì)象也可以包含內(nèi)部對(duì)象廓啊。
PUT http://127.0.0.1:9200/secisland/secilog/1
{
"region": "US",
"manager": {
"age": 30,
"name": {"first": "John", "last": "Smith"}
}
}
本質(zhì)上,文檔被簡單地索引為鍵值對(duì)的列表封豪,形如:
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John",
"manager.name.last": "Smith"
}
上面文檔的映射結(jié)構(gòu)為:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"region": {
"type": "string",
"index": "not_analyzed"
},
"manager": {
"properties": {
"age": {"type": "integer"},
"name": {
"properties": {
"first":{"type":"string"},
"last":{"type":"string"}
}
}
}
}
}
}
}
}
映射類型是一種對(duì)象類型谴轮,擁有參數(shù)字段,manager字段是一個(gè)內(nèi)部對(duì)象字段吹埠,manager.name字段是manager字段中的內(nèi)部對(duì)象字段第步。可以明確地設(shè)置type字段為object(默認(rèn)值)缘琅。對(duì)象數(shù)據(jù)類型的參數(shù)如下所示:
- dynamic——定義新的參數(shù)是否應(yīng)該動(dòng)態(tài)加入到已經(jīng)存在的對(duì)象中粘都。接受true(默認(rèn)),false和strict胯杭。
- enabled——賦值給對(duì)象字段的JSON值應(yīng)該被解析和索引(true驯杜,默認(rèn))還是完全忽略(false)。
- include_in_all——為對(duì)象內(nèi)的所有屬性設(shè)置include_in_all值做个。對(duì)象本身不添加到_all字段鸽心。
- properties——對(duì)象內(nèi)的字段可以是任意數(shù)據(jù)類型,包括對(duì)象數(shù)據(jù)類型居暖。新的屬性可以添加到已存在的對(duì)象中顽频。
3. 嵌套數(shù)據(jù)類型
嵌套數(shù)據(jù)類型是對(duì)象數(shù)據(jù)類型一個(gè)專門的版本,用來使一組對(duì)象被單獨(dú)地索引和查詢太闺。
(1)對(duì)象數(shù)組是如何攤平的
Lucene沒有內(nèi)部對(duì)象的概念糯景,所以Elasticsearch利用簡單的列表存儲(chǔ)字段名和值,將對(duì)象層次攤平。例如蟀淮,下面的文檔:
PUT http://127.0.0.1:9200/secisland/secilog/1
{
"group": "fans",
"user": {
{"first": "John", "last": "Smith"},
{"first": "Alice", "last": "White"}
}
}
把它內(nèi)部轉(zhuǎn)換為文檔最住,結(jié)構(gòu)如下:
{
"group": "fans",
"user.first": ["alice","john"],
"user.last": ["smith","white"]
}
user.first和user.last字段存在多值字段中,alice和white的關(guān)聯(lián)性丟失了怠惶。這個(gè)文檔可能錯(cuò)誤地匹配到關(guān)于alice和smith的查詢涨缚。
(2)對(duì)一組對(duì)象使用嵌套字段
如果需要對(duì)一組對(duì)象進(jìn)行索引而且保留數(shù)組中每個(gè)對(duì)象的獨(dú)立性,可以使用嵌套數(shù)據(jù)類型而不是對(duì)象數(shù)據(jù)類型策治。本質(zhì)上脓魏,嵌套對(duì)象將數(shù)組中的每個(gè)對(duì)象作為分離出來的隱藏文檔進(jìn)行索引。這也意味著每個(gè)嵌套對(duì)象可以獨(dú)立于其他對(duì)象被查詢通惫,示例如下茂翔。
創(chuàng)建的映射如下所示:
PUT PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"user": {"type": "nested"}
}
}
}
}
插入的數(shù)據(jù)如下所示:
PUT http://127.0.0.1:9200/secisland/secilog/1
{
"group": "fans",
"user": [
{"first": "John", "last": "Smith"},
{"first": "Alice", "last": "White"}
]
}
可以根據(jù)對(duì)象進(jìn)行搜索,但對(duì)象的條件要全匹配才能搜到履腋,例如搜索1如下所示:
POST http://127.0.0.1:9200/secisland/secilog/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{"match": { "user.first": "Alice}},
{"match": { "user.last": "Smith"}}
]
}
}
}
}
}
搜索2如下所示:
POST http://127.0.0.1:9200/secisland/secilog/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{"match": { "user.first": "Alice}},
{"match": { "user.last": "White"}}
]
}
}
}
}
}
user字段作為嵌套類型添加到索引中珊燎。搜索1匹配不到結(jié)果,因?yàn)锳lice和Smith不在同一個(gè)嵌套對(duì)象中府树;搜索2匹配到搜索結(jié)果俐末,因?yàn)锳lice和White在同一個(gè)嵌套對(duì)象中。
嵌套數(shù)據(jù)類型的字段參數(shù)如下所示:
- dynamic——定義新的參數(shù)是否應(yīng)該動(dòng)態(tài)加入到已經(jīng)存在的對(duì)象中奄侠。接受true(默認(rèn))卓箫,false和strict。
- include_in_all——設(shè)置所有嵌套對(duì)象屬性的include_in_all值垄潮。嵌套文檔沒有它們自身的_all字段烹卒,取而代之的是,值被添加到“根”文檔的_all 字段中弯洗。
- properties——嵌套對(duì)象的字段可以使任何數(shù)據(jù)類型旅急,包括嵌套對(duì)象類型。新的屬性可以被添加到已經(jīng)存在的嵌套對(duì)象中牡整。
3.2.3 地理數(shù)據(jù)類型
1. 地理點(diǎn)數(shù)據(jù)類型
地理點(diǎn)數(shù)據(jù)類型字段接受經(jīng)緯度對(duì)藐吮,可用于:
- 查找一定范圍內(nèi)的地理點(diǎn),這個(gè)范圍可以是相對(duì)于一個(gè)中心點(diǎn)的固定距離逃贝,也可以是多邊形或者地理散列單元谣辞。
- 通過地理位置或者相對(duì)于中心點(diǎn)的距離聚合文檔。
- 整合距離到文檔的相關(guān)性評(píng)分中沐扳。
- 通過距離對(duì)文檔進(jìn)行排序泥从。
指定字段類型為地理位置數(shù)據(jù)類型:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"location": {"type": "geo_point}
}
}
}
}
存儲(chǔ)地理位置數(shù)據(jù)有4種不同方式。下面分別介紹沪摄。
(1)請(qǐng)求:
PUT http://127.0.0.1:9200/secisland/secilog/1
{
"text": "Geo-point as an object",
"location": {"lat": 41.12, "lon": -71.34}
}
地理點(diǎn)參數(shù)形如對(duì)象參數(shù)躯嫉,擁有緯度和經(jīng)度鍵值對(duì)纱烘。
(2)請(qǐng)求
PUT http://127.0.0.1:9200/secisland/secilog/2
{
"text": "Geo-point as an string",
"location": "41.12,-71.34"
}
字符串地理點(diǎn)參數(shù)的格式為“緯度,經(jīng)度”祈餐。
(3)請(qǐng)求
PUT http://127.0.0.1:9200/secisland/secilog/3
{
"text": "Geo-point as an geohash",
"location": "drm3btev3e86"
}
散列地理點(diǎn)參數(shù)擂啥。
(4)請(qǐng)求
PUT http://127.0.0.1:9200/secisland/secilog/4
{
"text": "Geo-point as an array",
"location": [-71.34, 41.12]
}
地理點(diǎn)數(shù)組參數(shù),格式為[經(jīng)度帆阳,緯度]啤它。
注意:字符串地理點(diǎn)參數(shù)順序?yàn)椋ň暥龋?jīng)度)舱痘,地理點(diǎn)數(shù)組參數(shù)的順序?yàn)椋ń?jīng)度,緯度)离赫。地理點(diǎn)數(shù)據(jù)字段參數(shù)見表3-6芭逝。
表3-6 地理點(diǎn)字段參數(shù)
參數(shù) | 說明 |
---|---|
coere | 基于標(biāo)準(zhǔn)的-180:180/-90:90坐標(biāo)系統(tǒng)的經(jīng)度和緯度值。接受true和false(默認(rèn)) |
doc_values | 定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上渊胸,以便用于排序旬盯、聚合或者腳本。接受true(默認(rèn))或false參數(shù) |
geohash | 定義地理點(diǎn)是否應(yīng)該作為地理散列值在子字段.geohash中被索引翎猛。默認(rèn)為false胖翰,除非geohash_prefix參數(shù)值為true |
geohash_precision | 用于geohash和geohash_prefix選項(xiàng)的地理散列最大長度 |
geohash_prefix | 定義地理點(diǎn)是否應(yīng)該作為添加前綴的地理散列來進(jìn)行索引。默認(rèn)值為false |
ingore_malformed | 如果是true切厘,畸形的地理點(diǎn)會(huì)被忽略萨咳。如果是false(默認(rèn)),畸形地理點(diǎn)會(huì)拋出異常并丟棄整個(gè)文檔 |
lat_lon | 定義地理點(diǎn)是否應(yīng)該在子字段.lat和.lon中被索引到疫稿。接受true和false(默認(rèn)) |
precision_step | 控制每個(gè)經(jīng)緯點(diǎn)被索引的額外索引詞的數(shù)量饺谬。默認(rèn)值為16溜畅。與lat_lon參數(shù)的值無關(guān) |
2. 地理形狀數(shù)據(jù)類型
地理形狀數(shù)據(jù)類型有利于索引和搜索任意地理形狀,例如矩形和多邊形。無論是數(shù)據(jù)被索引還是在查詢執(zhí)行的過程中恰画,都可以使用地理形狀數(shù)據(jù)類型在地理點(diǎn)的基礎(chǔ)上包含地理形狀。
利用地理形狀查詢(geo_shape)來查詢文檔外驱,可以使用地理形狀數(shù)據(jù)類型屠凶。
(1)映射選項(xiàng)
地理形狀類型映射將geo_json幾何對(duì)象映射成地理形狀類型。為了啟用映射選項(xiàng)号坡,需要明確映射字段為地理形狀類型懊烤,參見表3-7。
表3-7 地理形狀數(shù)據(jù)類型映射選項(xiàng)
選項(xiàng) | 描述 |
---|---|
tree | 引用的前綴樹名:geohash或quadtree |
precision | 這個(gè)參數(shù)可以用來代替tree_levels來設(shè)置一個(gè)適當(dāng)?shù)膖ree_levels參數(shù)值筋帖。指定一個(gè)適當(dāng)?shù)木_度奸晴,Elasticsearch會(huì)計(jì)算匹配精確度的最佳tree_levels值。這個(gè)值應(yīng)該是一個(gè)數(shù)字日麸,后面跟著一個(gè)可選的距離單元寄啼〈猓可用的距離單元包括:in、inch墩划、yd涕刚、yard、mi乙帮、miled杜漠、km、kilometers察净、m驾茴、meters、cm氢卡、centimeters锈至、mm、millimeters |
tree_levels | 前綴樹使用的層的最大數(shù)量译秦∠考瘢可以用來控制形狀表示的精度以及因此索引的索引詞數(shù)量。默認(rèn)是選取前綴樹引用的默認(rèn)值筑悴。因?yàn)檫@個(gè)參數(shù)需要一定程度的底層實(shí)現(xiàn)的理解们拙,可以使用precision參數(shù)進(jìn)行替代。然而阁吝,即使使用precision參數(shù)砚婆,Elasticsearch本質(zhì)上只會(huì)使用并通過映射接口返回tree_levels |
strategy | 定義了如何在索引和搜索時(shí)表示形狀。會(huì)影響可用的功能突勇,所以建議讓Elasticsearch自動(dòng)設(shè)置這個(gè)參數(shù)射沟。有兩種可用的值:recursive和term。term僅支持點(diǎn)類型(points_only參數(shù)會(huì)自動(dòng)設(shè)置true)与境,recursive支持所有的形狀類型 |
distance_error_pct | 用于示意前綴樹應(yīng)該使用的精確值验夯。默認(rèn)是0.025(2.5%),最大支持的值為0.5 |
orientation | 定義了如何解讀多邊形/多邊形集合定點(diǎn)的順序摔刁。這個(gè)參數(shù)定義兩種坐標(biāo)系統(tǒng)規(guī)則(右手或左手)中的一個(gè)挥转,每一種坐標(biāo)系統(tǒng)可以用三種方式進(jìn)行指定。1.右手規(guī)則:right共屈、ccw绑谣、counterclockwise,2.左手規(guī)則:left拗引、cw借宵、clockwise。默認(rèn)方向(counterclockwise)遵循OGC標(biāo)準(zhǔn)矾削,定義了外環(huán)頂點(diǎn)按照逆時(shí)針的方向內(nèi)環(huán)頂點(diǎn)按順時(shí)針方向壤玫。在映射中對(duì)地理形狀字段設(shè)置這個(gè)參數(shù)豁护,可以明確設(shè)置坐標(biāo)列表中的頂點(diǎn)順序。 |
points_only | 設(shè)置這個(gè)選項(xiàng)為true(默認(rèn)為false)欲间,只對(duì)點(diǎn)形狀配置地理形狀字段類型(不支持多個(gè)點(diǎn)) |
(2)前綴樹
在索引中高效地表示形狀楚里,形狀被轉(zhuǎn)換到一系列表示為方格(通常被稱為“柵格”)的散列用于實(shí)現(xiàn)一個(gè)前綴樹。樹的概念來自該前綴樹使用多層網(wǎng)絡(luò)猎贴,每層增加精度級(jí)別來表示陸地班缎。這可以提高地圖的縮放級(jí)別或圖像的細(xì)節(jié)水平。
(3)空間策略
前綴樹的實(shí)現(xiàn)基于空間策略用來分解提供的形狀為近似方格她渴,每個(gè)策略解決這些問題:
- 哪種類型的形狀可以被索引达址。
- 形狀可以用于哪種類型的查詢操作。
- 每個(gè)字段是否可以保存多個(gè)形狀趁耗。
提供的這些策略實(shí)現(xiàn)(具有相應(yīng)的功能)見表3-8苏携。
表3-8 空間策略
策略 | 支持的形狀 | 支持的查詢 | 多形狀 |
---|---|---|---|
recursive | 所有 | INTERSECTS、DISJOINT对粪、WITHIN、CONTAINS | 是 |
term | 點(diǎn) | INTERSECTS | 是 |
(4)準(zhǔn)確性
地理形狀不提供100%的準(zhǔn)確性装蓬,并且取決于匹配值著拭,可能對(duì)確定的查詢返回一些誤判或漏判的結(jié)果。為了緩和這個(gè)問題牍帚,需要為tree_levels參數(shù)選擇一個(gè)合適的值來使用相應(yīng)的預(yù)期儡遮。例如:
{
"properties": {
"location": {
"type": "geo_shape",
"tree": "quadtree",
"precision": "1m"
}
}
}
這個(gè)映射將location字段映射到地理形狀類型,使用quad前綴樹并且精度1m暗赶。Elasticsearch轉(zhuǎn)換這個(gè)精度到tree_levels設(shè)置為26鄙币。
(5)性能方面的考慮
Elasticsearch使用前綴樹中的路徑作為索引和查詢中的索引詞。更高級(jí)別的精確值蹂随,會(huì)生成更多的索引詞十嘿。計(jì)算索引詞、加載到內(nèi)存岳锁、保存的磁盤也需要額外的性能花銷绩衷。
索引大小和合理水平的精確值的折中是50m。
(6)輸入結(jié)構(gòu)
用于表示形狀的GeoJSON格式見表3-9:
表3-9 GeoJSON格式
GeoJSON類型 | Elasticsearch類型 | 描述 |
---|---|---|
Point | point | 單獨(dú)地理坐標(biāo)點(diǎn) |
LineString | linestring | 一個(gè)任意的線激率,給出兩個(gè)或更多的點(diǎn) |
Polygon | polygon | 一個(gè)封閉的多邊形咳燕,第一個(gè)點(diǎn)和最后一個(gè)點(diǎn)必須匹配,需要N+1個(gè)頂點(diǎn)創(chuàng)建一個(gè)N多邊形乒躺,最少需要4個(gè)頂點(diǎn) |
MultiPoint | multipoint | 一組不連續(xù)的但是可能相關(guān)的點(diǎn) |
MultiLineString | multilinestring | 一組分離的線 |
MultiPolygon | multipolygon | 一組分離的多邊形 |
GeometryCollection | geometrycollection | 一種類似于multi*形狀的GeoJSON形狀招盲,多種類型可以共存(例如,一個(gè)點(diǎn)和一條線) |
N/A | envelope | 一個(gè)封閉的矩形嘉冒,通過制定左上角和右下角確定 |
N/A | circle | 一個(gè)圓曹货,通過制定圓心和帶單位的半徑來確定咆繁,默認(rèn)單位為METERS |
下面舉例說明這些格式。
Point是一個(gè)單獨(dú)的地理坐標(biāo)點(diǎn)控乾,比如當(dāng)前建筑的位置或者智能手機(jī)地理定位接口提供的確切位置么介。
{
"location": {
"type": "point",
"coordinates": [-77.03653, 38.897676]
}
}
Linestring通過兩個(gè)或更多的一組位置定義。只指定兩個(gè)點(diǎn)蜕衡,Linestring會(huì)表示一條直線壤短。指定更多的點(diǎn),可以創(chuàng)建任意的線慨仿。
{
"location": {
"type": "linestring",
"coordinates": [[-77.03653, 38.897676], [-77.009051, 38.889939]]
}
}
Polygon通過一列地理點(diǎn)列表進(jìn)行定義久脯。每個(gè)列表(外環(huán))中的第一個(gè)點(diǎn)和最后一個(gè)點(diǎn)必須相同(多邊形必須是封閉的)。
{
"location": {
"type": "polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
]
}
}
第一個(gè)數(shù)組表示多邊形的外環(huán)邊界镰吆,其他數(shù)組表示內(nèi)部形狀(”孔“)帘撰。
{
"location": {
"type": "polygon",
"coordinates" : [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
]
}
}
GeoJSON不強(qiáng)制指定頂點(diǎn)的順序,而在國際日期變更線和極點(diǎn)附近的多邊形是極有可能造成混亂的万皿。為了解決這種混亂摧找,開放地理空間信息聯(lián)盟(OGC)簡單特征訪問規(guī)范定義了這些定點(diǎn)順序:
- 外環(huán):逆時(shí)針方向。
- 內(nèi)環(huán)牢硅、孔:順時(shí)針方向蹬耘。
對(duì)于不跨越國際日期變更線的多邊形,頂點(diǎn)的順序?qū)τ贓lasticsearch來說是沒有關(guān)系的减余。Elasticsearch完全按照OGC制定的規(guī)范請(qǐng)求頂點(diǎn)综苔,否則,會(huì)創(chuàng)建一個(gè)意外的多邊形位岔,并且返回不符合預(yù)期的查詢/過濾結(jié)果如筛。
orientation參數(shù)可以在地里形狀數(shù)據(jù)類型字段創(chuàng)建映射的時(shí)候進(jìn)行定義,規(guī)定頂點(diǎn)的順序抒抬。也可以在每個(gè)文檔中進(jìn)行重寫:
{
"location": {
"type": "polygon",
"orientation": "clockwise",
"coordinates": [
[
[-177.0, 10.0], [176.0, 15.0], [172.0, 0.0], [176.0, -15.0], [-177.0, -10.0],
[-177.0, 10.0] ], [ [178.2, 8.2], [-178.8, 8.2], [-180.8, -8.8], [178.2, 8.8] ]
]
}
}
MultiPoint是GeoJSON點(diǎn)的列表杨刨,如下所示:
{
"location" :{"type":"multipoint", "coordinates": [[102.0, 2.0], [103.0, 2.0]]}
}
MultiLineString是GeoJSON線的列表,如下所示:
{
"location": {"type":"multilinestring", "coordinates": [
[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0] ],
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0] ],
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8] ]
]}
}
MultiPolygon是GeoJSON多邊形的列表擦剑,如下所示:
{
"location": {
"type": "multipolygon",
"coordinates": [
[ [[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]] ],
[ [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]] ,
[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]
],
]
}
}
GeometryCollection是GeoJSON地理集合對(duì)象的集合拭嫁,如下所示:
{
"location": {
"type": "geometrycollection",
"geometries": [
{"type": "point", "coordinates": [100.0, 0.0]},
{"type": "linestring", "coordinates": [ [100.0, 0.0], [102.0, 1.0] ]},
]
}
}
Envelope包含矩形左上角和右下角的坐標(biāo)值來表示矩形,例如:
{
"location": {"type": "envelope",
"coordinates": [ [-45.0, 45.0], [45.0, -45.0] ]}
}
Circle包含圓心和半徑:
{
"location": {
"type": "circle", "coordinates": [-45.0, 45.0], "radius": "100m"
}
}
注意抓于,radius是必要字段做粤。距離的單位默認(rèn)是米(METERS)。
(7)排序和取回形狀索引
由于形狀復(fù)雜的輸入結(jié)構(gòu)和索引表示捉撮,當(dāng)前不能直接通過字段排序或取回形狀怕品。地理形狀值只能通過_source字段取回。
3.2.4 專門數(shù)據(jù)類型
1. IPv4數(shù)據(jù)類型
IPv4字段本質(zhì)上是一個(gè)長整型字段巾遭,接受IPv4地址并作為長整型值進(jìn)行索引肉康。
添加映射:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"id_addr": {"type": "ip"}
}
}
}
}
插入數(shù)據(jù):
PUT http://127.0.0.1:9200/secisland/secilog/1
{"ip_addr":"192.168.1.1"}
IPv4數(shù)據(jù)類型的字段參數(shù)見表3-10
表3-10 IP字段參數(shù)
參數(shù) | 說明 |
---|---|
boost | 字段級(jí)索引加權(quán)闯估,接受浮點(diǎn)型數(shù)字參數(shù),默認(rèn)為1.0 |
doc_values | 定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上吼和,以便用于排序涨薪、聚合或者腳本。接受true(默認(rèn))或false參數(shù) |
include_in_all | 決定字段是否應(yīng)該包含在_all字段中炫乓。接受true或false參數(shù)刚夺。如果索引設(shè)置為no或者父對(duì)象字段設(shè)置include_in_all為false,參數(shù)默認(rèn)值為false末捣;其他情況下侠姑,默認(rèn)值為true |
index | 決定字段是否可以被用戶搜索。接受參數(shù)not_analyzed(默認(rèn))以及no |
null_value | 接受一個(gè)IPv4值替換所有null值箩做。默認(rèn)為null莽红,意味著字段作為缺失字段 |
precision_step | 控制索引的額外索引詞的數(shù)量來使范圍查詢更快速。默認(rèn)值為16 |
store | 決定字段值是否應(yīng)該存儲(chǔ)以及從_source字段分別獲取邦邦。接受參數(shù)true或false(默認(rèn)) |
注:IPv6地址現(xiàn)在還不提供支持
2. 單詞計(jì)數(shù)數(shù)據(jù)類型
單詞計(jì)數(shù)型字段本質(zhì)上是一整數(shù)型字段安吁,接受并分析字符串值,然后索引字符串中的單詞的個(gè)數(shù)燃辖。下面舉例說明鬼店。
添加映射:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"properties": {
"name": {
"type": "string",
"fields": {
"length": {"type":"token_count", "analyzer": "standard"}
}
}
}
}
}
}
插入數(shù)據(jù):
PUT http://127.0.0.1:9200/secisland/secilog/1
{"name":"John Smith"}
嚴(yán)格來說,單詞計(jì)數(shù)類型計(jì)算位置增量而不是統(tǒng)計(jì)單詞郭赐。這意味著即使分析器過濾掉一部分單詞,它們也會(huì)被包含在計(jì)數(shù)中确沸。單詞計(jì)數(shù)類型的字段參數(shù)如表3-11所示捌锭。
表3-11 單詞計(jì)數(shù)型字段參數(shù)
參數(shù) | 說明 |
---|---|
analyzer | 必要字段,定義用來分析字符串值的分析器 |
boost | 字段級(jí)索引加權(quán)罗捎,接受浮點(diǎn)型數(shù)字參數(shù)观谦,默認(rèn)為1.0 |
doc_values | 定義字段是否應(yīng)該以列跨度的方式存儲(chǔ)在磁盤上,以便用于排序桨菜、聚合或者腳本豁状。接受true(默認(rèn))或false參數(shù) |
include_in_all | 決定字段是否應(yīng)該包含在_all字段中。接受true或false參數(shù)倒得。如果索引設(shè)置為no或者父對(duì)象字段設(shè)置include_in_all為false泻红,參數(shù)默認(rèn)值為false;其他情況下霞掺,默認(rèn)值為true |
index | 決定字段是否可以被用戶搜索谊路。接受參數(shù)not_analyzed(默認(rèn))以及no |
null_value | 接受一個(gè)與字段相同類型的數(shù)字型值替換所有null值。默認(rèn)為null菩彬,意味著字段被作為缺失字段 |
precision_step | 控制索引的額外索引詞的數(shù)量來使范圍查詢更快速缠劝。默認(rèn)值為32 |
store | 決定字段值是否應(yīng)該存儲(chǔ)以及從_source字段分別獲取潮梯。接受參數(shù)true或false(默認(rèn)) |
3.3 元字段
每個(gè)文檔都有與之關(guān)聯(lián)的元數(shù)據(jù),元字段是為了保證系統(tǒng)正常運(yùn)轉(zhuǎn)的內(nèi)置字段惨恭,比如index表示索引字段秉馏,_type表示映射類型字段和_id表示文檔主鍵字段,這些字段都是以下劃線開頭的脱羡。當(dāng)映射類型被創(chuàng)建的時(shí)候萝究,可以自定義一些元字段的行為,例如標(biāo)識(shí)元字段轻黑、文檔來源元字段糊肤、索引元字段、路由元字段等氓鄙。參見表3-12到表3-16.
表3-12 標(biāo)識(shí)元字段
參數(shù) | 說明 |
---|---|
_index | 文檔所屬的索引 |
_uid | 包含_type和_id的混合字段 |
_type | 問的的映射類型 |
_id | 文檔的ID |
表3-13 文檔來源元字段
參數(shù) | 說明 |
---|---|
_source | 作為文檔內(nèi)容的原始JSON |
_size | _source元字段占用的字節(jié)數(shù)馆揉,通過mapper-size插件提供 |
表3-14 索引元字段
參數(shù) | 說明 |
---|---|
_all | 索引所有字段的值 |
_field_names | 文檔中所有包含非空值的字段 |
_timestamp | 關(guān)聯(lián)文章的時(shí)間戳,可以手動(dòng)指定或者自動(dòng)生成 |
_ttl | 定義文檔被自動(dòng)刪除之前的存活時(shí)間 |
表3-15 路由元字段
參數(shù) | 說明 |
---|---|
_parent | 用于在映射類型之間創(chuàng)建父子關(guān)系 |
_rounting | 一個(gè)自定義的路由值抖拦,路由文檔到一個(gè)特定的分片 |
表3-16 其他元字段
參數(shù) | 說明 |
---|---|
_meta | 應(yīng)用特定的元字段 |
3.3.1 _all字段
_all字段是一個(gè)特殊的包含全部內(nèi)容的字段升酣,在一個(gè)大字符串中關(guān)聯(lián)所有其他字段的值,使用空格作為分隔符态罪∝眩可以被分析和索引但不會(huì)被存儲(chǔ)。使用_all字段可以對(duì)文檔的值進(jìn)行搜索而不必知道包含所需值的字段名复颈。當(dāng)面對(duì)一個(gè)新的數(shù)據(jù)集的時(shí)候绩聘,_all字段是非常有用的選項(xiàng)。
插入數(shù)據(jù):
PUT http://127.0.0.1:9200/secisland/secilog/1
{
"first_name": "John",
"last_name": "Smith",
"date_of_birth": "1980-10-24"
}
利用_all字段進(jìn)行搜索:
GET http://127.0.0.1:9200/secisland/_search
{
"query": {"match": {"_all": "john smith 1970"}}
}
_all字段包含的索引詞:["john", "smith", "1970", "10", "24"]
注解:date_of_birth字段作為日期型字段耗啦,會(huì)索引一個(gè)索引詞1970-10-24 00:00:00 UTC凿菩。但是,_all字段將所有的值作為字符串帜讲,所以日期值作為三個(gè)字符串被索引:"1970","10", "24"衅谷。
_all字段就是一個(gè)字符串字段,接受與字符串型字段相同的參數(shù)似将,包括analyzer,index_options和store获黔。
_all字段關(guān)聯(lián)字段值的時(shí)候,丟失了短字段(高相關(guān)性)和長字段(低相關(guān)性)之間的區(qū)別在验。當(dāng)相關(guān)性是重要搜索條件的時(shí)候玷氏,應(yīng)該明確指出查詢字段。
_all字段的使用需要額外的處理器周期腋舌,并且耗費(fèi)更多的磁盤空間预茄。如果不需要的話,可以完全禁用或者在每個(gè)字段的基礎(chǔ)上自定義。
3.3.2 _field_names字段
_field_names字段索引文檔中所有包含非空值的字段名稱耻陕。_field_names字段擁有存在查詢和缺失查詢的情況下拙徽,查找指定字段擁有非空值的文檔是否存在。
_field_names字段的值可以用于查詢诗宣、聚合以及腳本:
PUT http://127.0.0.1:9200/secisland/secilog/1
{"title": "This is a document"}
PUT http://127.0.0.1:9200/secisland/secilog/1
{"title": "This is another document", "body": "This document has a body"}
GET http://127.0.0.1:9200/secisland/_search
{
"query": {"terms": {"_field_names":["title"]}},
"aggs": {
"Field names": {
"terms": {"field": "_field_names", "size": 10}
}
},
"script_fields": {
"Field names": {"scripts": "doc['_field_names']" }
}
}
3.3.3 _id字段
每個(gè)被索引的文檔都關(guān)聯(lián)一個(gè)_type字段和一個(gè)_id字段膘怕。_id字段沒有索引,它的值可以從_uid字段自動(dòng)生成召庞。
_id字段的值可以在查詢以及腳本中訪問岛心,但是在聚合或者排序的時(shí)候,要使用_uid字段而不能用_id字段篮灼。
在查詢和腳本中使用_id字段的示例如下:
GET http://127.0.0.1:9200/secisland/_search
{
"query": {
"terms": {"_id": ["1", "2"]}
},
"script_fields": {
"UID": {"script": "doc['_id']"}
}
}
3.3.4 _index字段
在多個(gè)索引中執(zhí)行查詢的時(shí)候忘古,有時(shí)需要添加查詢子句來關(guān)聯(lián)特定的索引文檔。_index字段可以匹配包含某個(gè)文檔的索引诅诱。在term或terms查詢髓堪、聚合、腳本以及排序的時(shí)候娘荡,可以訪問_index字段的值干旁。
_index是一個(gè)虛擬字段,不作為一個(gè)真實(shí)的字段添加到Lucene索引中炮沐。這意味著可以在term或terms查詢(或任何重寫term查詢的查詢争群,比如match、query_string或者simple_query_string查詢)中使用_index字段大年,但是不支持prefix换薄、wildcard、regexp或fuzzy查詢翔试。示例如下:
GET http://127.0.0.1:9200/index_1,index_2/_search
{
"query": {"terms": {"_index": ["index_1", "index_2"] }},
"aggs": {"indices": {"terms": {"field":"_index", "size": 10}}},
"sort": [{"_index": {"order":"asc}}],
"script_fields": {"index_name": {"script": "doc['_index']" }}
}
3.3.5 _meta字段
每個(gè)映射類型都可以擁有自定義的元數(shù)據(jù)轻要。這些元數(shù)據(jù)對(duì)Elasticsearch來說毫無用處,但是可以用來存儲(chǔ)應(yīng)用程序的特定元數(shù)據(jù):
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"user": {
"_meta": {
"class": "MyApp::User,
"version": {"min": "1.0", "max":"1.3"}
}
}
}
}
3.3.6 _parent字段
在同一個(gè)索引中通過創(chuàng)建映射類型可以在文檔間建立父子關(guān)系遏餐。
創(chuàng)建映射的代碼如下:
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"my_parent": {},
"my_child": {
"_parent": {"type": "my_parent"}
}
}
}
插入父文檔的代碼如下:
PUT http://127.0.0.1:9200/secisland/my_parent/1
{"text": "This is a parent document"}
插入子文檔伦腐,并指出父文檔的代碼如下:
PUT http://127.0.0.1:9200/secisland/my_child/2?parent=1
{"text": "This is a child document"}
PUT http://127.0.0.1:9200/secisland/my_child/3?parent=1
{"text": "This is another child document"}
1. 父子限制
父類型和子類型必須是不同的赢底,即父子關(guān)系不能建立在相同類型的文檔之間失都。
_parent的type設(shè)置智能只想一個(gè)當(dāng)前不存在的類型。這意味著一個(gè)類型被創(chuàng)建之后就無法成為父類型幸冻。
父子文檔必須索引在相同的分片上粹庞。parent編號(hào)用于作為子文檔的路由值,確保子文檔被索引到父文檔所在的分片中洽损。這意味著當(dāng)獲取庞溜、刪除或更新子文檔的時(shí)候,需要提供相同的parent值。
2. 整體序數(shù)
使用整體序數(shù)可以加快建立父子關(guān)系流码。分片發(fā)生任何改變之后又官,整體序數(shù)都徐帥進(jìn)行重建。分片中存儲(chǔ)的父編碼值越多漫试,為_parent字段重建整體序數(shù)所花 的時(shí)間就越長六敬。
整體序數(shù)在默認(rèn)情況下屬于懶創(chuàng)建:刷新之后的第一次父子查詢或聚合會(huì)出發(fā)整體序數(shù)的創(chuàng)建,這可能會(huì)給用戶的使用引入一個(gè)明顯的延遲驾荣⊥夤梗可以使用參數(shù)將整體序數(shù)的創(chuàng)建時(shí)間由查詢觸發(fā)改到刷新觸發(fā):
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"my_parent": {},
"my_child": {
"_parent": {
"type": "my_parent",
"fielddata": {"loading": "eager_global_ordinals"}
}
}
}
}
3.3.7 _routing字段
文檔在索引中利用下面的公式路由到特定的分片:
shard_num = hash(_routing) % num_primary_shards
_routing字段的默認(rèn)值使用的是文檔的_id字段。如果存在父文檔播掷,則使用文檔的_parent編號(hào)审编。
可以通過為每個(gè)文檔指定一個(gè)自定義的路由值來實(shí)現(xiàn)自定義的路由方式:
PUT http://127.0.0.1:9200/secisland/secilog/1?routing=user1
{"title": "This is a document"}
這個(gè)文檔使用user1作為路由值,而不是它的ID歧匈,在獲取垒酬、刪除和更新文檔的時(shí)候需要提供相同的路由值。
_routing字段可以在查詢眯亦、聚合伤溉、腳本以及排序的時(shí)候訪問:
GET http://127.0.0.1:9200/secisland/_search
{
"query": {
"terms": {"_routing": ["user1] }
},
"aggs": {
"Routing values": {
"terms": {"field": "_routing", "size": 10}
}
},
"sort": [
{
"_routing": {"order": "desc}
}
],
"script_fields": {
"Routing value": {"script":"doc['_routing']" }
}
}
1. 利用自定義路由進(jìn)行搜索
自定義路由可以降低搜索壓力。搜索請(qǐng)求可以僅僅發(fā)送到匹配指定路由值的分片而不是廣播到所有分片妻率,如下所示:
GET http://127.0.0.1:9200/secisland/_search?routing=user1,user2
{
"query": {
"match": {"title": "document" }
}
}
搜索請(qǐng)求僅在關(guān)聯(lián)路由值user1和user2的分片上執(zhí)行乱顾。
2. 使路由值成為必選項(xiàng)
使用自定義路由索引、獲取宫静、刪除或更新文檔時(shí)走净,提供路由值是很重要的。
忘記路由值會(huì)導(dǎo)致文檔被一個(gè)以上的分片索引孤里。作為保障伏伯,_routing字段可以被設(shè)置,應(yīng)使自定義路由值成為所有CRUD操作的必選項(xiàng):
PUT http://127.0.0.1:9200/secisland
{
"mappings": {
"secilog": {
"_routing": {"required": true}
}
}
}