Elasticsearch實踐(三):Mapping
版本:Elasticsearch 6.2.4。
Mapping類似於資料庫中的表結構定義,主要作用如下:
定義Index下欄位名(Field Name)
定義欄位的型別,比如數值型,字串型、布林型等
定義倒排索引的相關配置,比如是否索引、記錄postion等
Mapping完整的內容可以分為四部分內容:
欄位型別(Field datatypes)
元欄位(Meta-Fields)
Mapping引數配置(Mapping parameters)
動態Mapping(Dynamic Mapping)
自動Mapping
如果沒有手動設定Mapping,Elasticsearch預設會自動解析出型別,且每個欄位以第一次出現的為準。
下面我們先看一下Elasticsearch預設建立的Mapping是什麼樣的。
首先我們建立一個索引:
PUT /user/
查詢索引資訊:
GET /user
結果:
{ "user": { "aliases": {}, "mappings": {}, "settings": { "index": { "creation_date": "1540044686190", "number_of_shards": "5", "number_of_replicas": "1", "uuid": "_K5b8w7jRiuthf7QeQZhdw", "version": { "created": "5060299" }, "provided_name": "user" } } } }
增加一條資料:
PUT /user/doc/1{ "name":"Allen Yer", "job":"php", "age":22} PUT /user/doc/2{ "name":"Allen Yer", "job":0, "age":22}
查詢資料是否新增成功:
GET /user/doc/_count
結果:
{ "count": 2, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 } }
count為2,說明新增成功。然後我們查詢下 mapping :
{ "user": { "mappings": { "doc": { "properties": { "age": { "type": "long" }, "job": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } } }
發現自動為每個欄位設定了型別:
name: text型別,另外額外增加了
name.keyword
欄位,keyword
型別;job:text型別,另外額外增加了
job.keyword
欄位,keyword
型別;雖然第二次資料新增是數字型別,但還是以第一次為主;age:long型別。
大家可以把索引刪掉,將新增資料調整為先新增第2條,再新增第一條,發現報錯了:
DELETE /userPUT /user/doc/2{ "name":"Allen Yer", "job":0, "age":22} PUT /user/doc/1{ "name":"Allen Yer", "job":"php", "age":22}
報錯:
{ "error": { "root_cause": [ { "type": "mapper_parsing_exception", "reason": "failed to parse [job]" } ], "type": "mapper_parsing_exception", "reason": "failed to parse [job]", "caused_by": { "type": "number_format_exception", "reason": "For input string: "php"" } }, "status": 400}
也能說明以第一次為主以欄位第一次的值型別為準。這也說明了預設建立mapping可能不是我們想要的,這就需要手動建立mapping,好處有:
提前指定欄位(透過設定甚至可以達到禁止自動增加欄位的效果)
合理設定欄位型別,防止分詞過多或者解析不合理。分詞過大會導致磁碟空間佔用大。
手動建立mapping
這次我們刪掉mapping,並手動建立一個:
DELETE /userPUT /user/ { "mappings": { "doc": { "properties": { "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "age": { "type": "long", "index": false }, "job": { "type": "keyword" }, "intro":{ "type":"text" }, "create_time": { "type": "date", "format": "epoch_second" } } } } }
欄位型別說明:
name:text型別,會進行分詞,支援模糊檢索。
name.keyword : 這相當於是巢狀了一個欄位,keyword型別,只能精確匹配,不支援分詞。超過256字元長度不索引,也就沒法搜尋到。
age:long型別,支援精確匹配。
job:keyword型別,只能精確匹配,不支援分詞。
intro:text型別,會進行分詞,支援模糊檢索。
create_time:date型別,支援10位時間戳。
注意:mapping生成後是不允許修改(包括刪除)的。所以需要提前合理的的定義mapping。
欄位型別
Elasticsearch支援文件中欄位的許多不同資料型別:
普通資料型別
字串型別
有text
和 keyword
2種 。其中 text
支援分詞,用於全文搜尋;keyword
不支援分詞,用於聚合和排序。在舊的ES裡這兩個型別由string
表示。
如果安裝了IK分詞外掛,我們可以為text
型別指定IK分詞器。一般來說,對於字串型別,如果:
1) 模糊搜尋+精確匹配,一般是name或者title欄位:
"name": { "type": "text", "analyzer": "ik_smart", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }
2) 模糊搜尋,一般是內容詳情欄位:
"content": { "type": "text", "analyzer": "ik_smart" }
3) 精確匹配:
"name": { "type": "keyword" }
4) 不需要索引:
"url": { "type": "keyword", "index": false }
數字型別
支援 long,integer,short,byte,double,float,half_float,scaled_float。具體說明如下:
long
帶符號的64位整數,其最小值為-2^63
,最大值為(2^63)-1
。integer
帶符號的32位整數,其最小值為-2^31
,最大值為(23^1)-1
。short
帶符號的16位整數,其最小值為-32,768,最大值為32,767。byte
帶符號的8位整數,其最小值為-128,最大值為127。double
雙精度64位IEEE 754浮點數。float
單精度32位IEEE 754浮點數。half_float
半精度16位IEEE 754浮點數。scaled_float
縮放型別的的浮點數。需同時配置縮放因子(scaling_factor)一起使用。
對於整數型別(byte,short,integer和long)而言,我們應該選擇這是足以使用的最小的型別。這將有助於索引和搜尋更有效。
對於浮點型別(float、half_float和scaled_float),-0.0
和+0.0
是不同的值,使用term
查詢查詢-0.0
不會匹配+0.0
,同樣range
查詢中上邊界是-0.0
不會匹配+0.0
,下邊界是+0.0
不會匹配-0.0
。
其中scaled_float
,比如價格只需要精確到分,price
為57.34
的欄位縮放因子為100
,存起來就是5734
。優先考慮使用帶縮放因子的scaled_float
浮點型別。
示例:
PUT my_index { "mappings": { "_doc": { "properties": { "status": { "type": "byte" }, "year": { "type": "short" }, "id": { "type": "long" }, "price": { "type": "scaled_float", "scaling_factor": 100 } } } } }
日期型別
型別為 date
。
JSON本身是沒有日期型別的,因此Elasticsearch中的日期可以是:
包含格式化日期的字串。
一個13位long型別表示的毫秒時間戳( milliseconds-since-the-epoch)。
一個integer型別表示的10位普通時間戳(seconds-since-the-epoch)。
在Elasticsearch內部,日期型別會被轉換為UTC(如果指定了時區)並儲存為long型別表示的毫秒時間戳。
日期型別可以使用使用format
自定義,預設預設值:"strict_date_optional_time||epoch_millis"
:
"postdate": { "type": "date", "format": "strict_date_optional_time||epoch_millis" }
format
有很多內建型別,這裡列舉部分說明:
strict_date_optional_time, date_optional_time
通用的ISO日期格式,其中日期部分是必需的,時間部分是可選的。例如 "2015-01-01"或"2015/01/01 12:10:30"。epoch_millis
13位毫秒時間戳epoch_second
10位普通時間戳
其中strict_
開頭的表示嚴格的日期格式,這意味著,年、月、日部分必須具有前置0。
更多日期格式詳見:
當然也可以自定義日期格式,例如:
"postdate":{ "type":"date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd" }
注意:如果新文件的欄位的值與format裡設定的型別不相容,ES會返回失敗。示例:
PUT my_index { "mappings": { "_doc": { "properties": { "date": { "type": "date", "format":"epoch_millis" } } } } } PUT my_index/_doc/1{ "date":1543151405000} PUT my_index/_doc/2{ "date":1543151405} PUT my_index/_doc/3{ "date":"2018-11-25 21:10:43"} GET my_index/_doc/_search
第3條資料插入失敗,因為只接受長整數的時間戳,字串型別的日期是不匹配的。第2條的值只有10位數,雖然值是不正確的,但是在epoch_millis
的取值範圍內,所以也是成功的。
布林型別
型別為 boolean
。
二進位制型別
型別為 binary
。
範圍型別
integer_range,float_range,long_range,double_range,date_range
複雜型別
陣列資料型別
在ElasticSearch中,沒有專門的陣列(Array)資料型別,但是,在預設情況下,任意一個欄位都可以包含0或多個值,這意味著每個欄位預設都是陣列型別,只不過,陣列型別的各個元素值的資料型別必須相同。在ElasticSearch中,陣列是開箱即用的(out of box),不需要進行任何配置,就可以直接使用。,例如:
字元型陣列: [ "one", "two" ]
整型陣列:[ 1, 2 ]
陣列型陣列:[ 1, [ 2, 3 ]]
等價於[ 1, 2, 3 ]
物件資料型別
object 對於單個JSON物件。JSON天生具有層級關係,文件可以包含巢狀的物件。巢狀資料型別
nested 對於JSON物件的陣列
Geo資料型別
地理點資料型別
geo_point 對於緯度/經度點Geo-Shape資料型別
geo_shape 對於像多邊形這樣的複雜形狀
專用資料型別
IP資料型別
ip 用於IPv4和IPv6地址完成資料型別
completion 提供自動完成的建議令牌計數資料型別
token_count 計算字串中的標記數mapper-murmur3
murmur3 在索引時計算值的雜湊值並將它們儲存在索引中過濾器型別
接受來自query-dsl的查詢join 資料型別
為同一索引中的文件定義父/子關係
多欄位
為不同目的以不同方式索引相同欄位通常很有用。例如,string可以將欄位對映為text用於全文搜尋的keyword欄位,以及用於排序或聚合的欄位。或者,您可以使用standard分析儀, english分析儀和 french分析儀索引文字欄位。
元欄位
_all
該欄位用於在沒有指定具體欄位的情況下進行模糊搜尋,可以搜尋全部欄位的內容。
原理是將所有欄位的內容視為字串,拼在一起放在一個_all
欄位上,但這個欄位預設是不被儲存的,可以被搜尋。在query_string
與 simple_query_string
查詢(Kibana搜尋框用的這種查詢方式)預設也是查詢_all
欄位。
6.x
版本被預設關閉。
相關設定:
PUT my_index { "mappings": { "my_type": { "_all": { "enabled": true, "store": false }, "properties": {} } }, "settings": { "index.query.default_field": "_all" } }
上述配置在5.x
版本是預設配置:
預設開啟
_all
欄位預設不儲存
_all
欄位預設搜尋
_all
欄位
如果從CPU效能及磁碟空間考慮,可以考慮可以完全禁用或基於每個欄位自定義_all
欄位。
假設_all
欄位被禁用,則URI搜尋請求、 query_string
和simple_query_string
查詢將無法將其用於查詢。我們可以將它們配置為其他欄位:透過定義 index.query.default_field
屬性。
_source
這個欄位用於儲存原始的JSON文件內容,本身不會被索引,但是搜尋的時候被返回。如果沒有該欄位,雖然還能正常搜尋,但是返回的內容不知道對應的是什麼。
示例:
GET /user/doc/_search?q=name
結果:
{ "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "doc", "_id": "1", "_score": 0.2876821, "_source": { "name": "this is test name", "age": 22, "job": "java", "intro": "the intro can not be searched by singal", "intro2": "去朝陽公園", "create_time": 1540047542 } } ] } }
搜尋結果就包含_source
欄位,儲存的是原始文件內容。如果被禁用,只知道有匹配內容,但是無法知道返回的是什麼。所以需要謹慎關閉該欄位。
如果想禁用該欄位,可以在建立Mapping的時候,設定_:
{ "mappings": { "_doc": { "_source": { "enabled": false } } } }
_type
ElasticSearch裡面有 index 和 type 的概念:index稱為索引,type為文件型別,一個index下面有多個type,每個type的欄位可以不一樣。這類似於關係型資料庫的 database 和 table 的概念。
但是,ES中不同type下名稱相同的filed最終在Lucene中的處理方式是一樣的。所以後來ElasticSearch團隊想去掉type,於是在6.x版本為了向下相容,一個index只允許有一個type。
該欄位再在6.0.0中棄用。在Elasticsearch 6.x 版本中建立的索引只能包含單個type。在5.x中建立的含有多個type的索引將繼續像以前一樣在Elasticsearch 6.x中執行。type 將在Elasticsearch 7.0.0中完全刪除。
詳見:https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html
參考
1、Mapping | Elasticsearch Reference [6.4] | Elastic
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
2、Elasticsearch 6.x Mapping設定 - 小旋鋒
https://mp.weixin.qq.com/s/pBPH-wccdY1oslpqGgAHBg
3、整理的es中的mapping方面的內容 - 辛星,前進的路上. - CSDN部落格
https://blog.csdn.net/xinguimeng/article/details/51588583
4、[譯]ElasticSearch資料型別--string型別已死, 字串資料永生 - 牧曦之晨 - SegmentFault 思否
5、ElasticSearch的_all域 | 學步園
6、圖解Elasticsearch中的_source、_all、store和index屬性 - 1.01^365=37.78 (Lucene、ES、ELK開發交流群: 370734940) - CSDN部落格
https://blog.csdn.net/napoay/article/details/62233031
7、Elasticsearch - 自動檢測及動態對映Dynamic Mapping - 上善若水,水善利萬物而不爭。 - CSDN部落格
https://blog.csdn.net/xifeijian/article/details/51090338
8、Field datatypes | Elasticsearch Reference [6.2] | Elastic
作者:飛鴻影~
出處:https://www.cnblogs.com/52fhy/p/10017518.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/758/viewspace-2817996/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Elasticsearch MappingElasticsearchAPP
- Elasticsearch核心技術(三):Mapping設定ElasticsearchAPP
- ElasticSearch(二):MappingElasticsearchAPP
- ElasticSearch 中的 MappingElasticsearchAPP
- Elasticsearch Mapping型別修改ElasticsearchAPP型別
- 【ElasticSearch】ElasticSearch 7.x 預設不在支援指定索引型別 Failed to parse mapping [_doc]: Root mapping definitioElasticsearch索引型別AIAPP
- Elasticsearch調優實踐Elasticsearch
- ElasticSearch7.3 學習之Mapping核心資料型別及dynamic mappingElasticsearchAPP資料型別
- [Elasticsearch] ES 的Mapping 設計在實際場景中應用ElasticsearchAPP
- Elasticsearch 索引容量管理實踐Elasticsearch索引
- Elasticsearch從入門到放棄:瞎說MappingElasticsearchAPP
- 如何設計一個高效能 Elasticsearch mappingElasticsearchAPP
- Elasticsearch 7.2 在 Laravel 中實踐ElasticsearchLaravel
- 實踐003-elasticsearch之analyzerElasticsearch
- KubeSphere 接入外部 Elasticsearch 最佳實踐Elasticsearch
- ClickHouse與Elasticsearch壓測實踐Elasticsearch
- Elasticsearch在Laravel中的實踐ElasticsearchLaravel
- 滴滴 Elasticsearch 多叢集架構實踐Elasticsearch架構
- 貸前系統ElasticSearch實踐總結Elasticsearch
- 實踐001-elasticsearch的index、create、updateElasticsearchIndex
- 實踐005-elasticsearch的Search API概覽ElasticsearchAPI
- TDD 實踐-FizzFuzzWhizz(三)
- DHCP最佳實踐(三)
- Elasticsearch學習(三)springboot整合ElasticSearchElasticsearchSpring Boot
- 基於 MySQL Binlog 的 Elasticsearch 資料同步實踐MySqlElasticsearch
- elasticsearch實戰三部曲之三:搜尋操作Elasticsearch
- Docker入門實踐(三)Docker
- Elasticsearch學習系列三(搜尋案例實戰)Elasticsearch
- 讓Elasticsearch飛起來!——效能優化實踐乾貨Elasticsearch優化
- 讓 Elasticsearch 飛起來!——效能優化實踐乾貨Elasticsearch優化
- 【主流技術】ElasticSearch 在 Spring 專案中的實踐ElasticsearchSpring
- 用 Python 優雅地玩轉 Elasticsearch:實用技巧與最佳實踐PythonElasticsearch
- Java中Elasticsearch 實現分頁方式(三種方式)JavaElasticsearch
- React最佳實踐嘗試(三)React
- Elasticsearch在華泰證券內部的應用實踐Elasticsearch
- ES 筆記四十七:Elasticsearch 資料建模佳實踐筆記Elasticsearch
- Elasticsearch(三):索引查詢Elasticsearch索引
- ElasticSearch結合Logstash(三)Elasticsearch