版本:Elasticsearch 6.2.4。
Mapping相似於數據庫中的表結構定義,主要做用以下:php
Mapping完整的內容能夠分爲四部份內容:html
若是沒有手動設置Mapping,Elasticsearch默認會自動解析出類型,且每一個字段以第一次出現的爲準。java
下面咱們先看一下Elasticsearch默認建立的Mapping是什麼樣的。 數據庫
首先咱們建立一個索引:segmentfault
PUT /user/
查詢索引信息:數組
GET /user
結果:app
{ "user": { "aliases": {}, "mappings": {}, "settings": { "index": { "creation_date": "1540044686190", "number_of_shards": "5", "number_of_replicas": "1", "uuid": "_K5b8w7jRiuthf7QeQZhdw", "version": { "created": "5060299" }, "provided_name": "user" } } } }
增長一條數據:elasticsearch
PUT /user/doc/1 { "name":"Allen Yer", "job":"php", "age":22 } PUT /user/doc/2 { "name":"Allen Yer", "job":0, "age":22 }
查詢數據是否新增成功:ide
GET /user/doc/_count
結果:post
{ "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.keyword
字段,keyword
類型;job.keyword
字段,keyword
類型;雖然第二次數據新增是數字類型,但仍是以第一次爲主;你們能夠把索引刪掉,將新增數據調整爲先新增第2條,再新增第一條,發現報錯了:
DELETE /user PUT /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,並手動建立一個:
DELETE /user PUT /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" } } } } }
字段類型說明:
注意: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。具體說明以下:
帶符號的64位整數,其最小值爲-2^63
,最大值爲(2^63)-1
。
帶符號的32位整數,其最小值爲-2^31
,最大值爲(23^1)-1
。
帶符號的16位整數,其最小值爲-32,768,最大值爲32,767。
帶符號的8位整數,其最小值爲-128,最大值爲127。
雙精度64位IEEE 754浮點數。
單精度32位IEEE 754浮點數。
半精度16位IEEE 754浮點數。
縮放類型的的浮點數。需同時配置縮放因子(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中的日期能夠是:
在Elasticsearch內部,日期類型會被轉換爲UTC(若是指定了時區)並存儲爲long類型表示的毫秒時間戳。
日期類型可使用使用format
自定義,默認缺省值:"strict_date_optional_time||epoch_millis"
:
"postdate": { "type": "date", "format": "strict_date_optional_time||epoch_millis" }
format
有不少內置類型,這裏列舉部分說明:
通用的ISO日期格式,其中日期部分是必需的,時間部分是可選的。例如 "2015-01-01"或"2015/01/01 12:10:30"。
13位毫秒時間戳
10位普通時間戳
其中strict_
開頭的表示嚴格的日期格式,這意味着,年、月、日部分必須具備前置0。
更多日期格式詳見: https://www.elastic.co/guide/...
固然也能夠自定義日期格式,例如:
"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_point 對於緯度/經度點
geo_shape 對於像多邊形這樣的複雜形狀
ip 用於IPv4和IPv6地址
completion 提供自動完成的建議
token_count 計算字符串中的標記數
murmur3 在索引時計算值的哈希值並將它們存儲在索引中
接受來自query-dsl的查詢
爲同一索引中的文檔定義父/子關係
爲不一樣目的以不一樣方式索引相同字段一般頗有用。例如,string能夠將字段映射爲text用於全文搜索的keyword字段,以及用於排序或聚合的字段。或者,您可使用standard分析儀, english分析儀和 french分析儀索引文本字段。
該字段用於在沒有指定具體字段的狀況下進行模糊搜索,能夠搜索所有字段的內容。
原理是將全部字段的內容視爲字符串,拼在一塊兒放在一個_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
屬性。
這個字段用於存儲原始的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 } } } }
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/...
一、Mapping | Elasticsearch Reference [6.4] | Elastic
https://www.elastic.co/guide/...
二、Elasticsearch 6.x Mapping設置 - 小旋鋒
https://mp.weixin.qq.com/s/pB...
三、整理的es中的mapping方面的內容 - 辛星,前進的路上. - CSDN博客
https://blog.csdn.net/xinguim...
四、[譯]ElasticSearch數據類型--string類型已死, 字符串數據永生 - 牧曦之晨 - SegmentFault 思否
https://segmentfault.com/a/11...
五、ElasticSearch的_all域 | 學步園
https://www.xuebuyuan.com/205...
六、圖解Elasticsearch中的_source、_all、store和index屬性 - 1.01^365=37.78 (Lucene、ES、ELK開發交流羣: 370734940) - CSDN博客
https://blog.csdn.net/napoay/...
七、Elasticsearch - 自動檢測及動態映射Dynamic Mapping - 上善若水,水善利萬物而不爭。 - CSDN博客
https://blog.csdn.net/xifeiji...
八、Field datatypes | Elasticsearch Reference [6.2] | Elastic
https://www.elastic.co/guide/...