ES mapping 詳解
1 mapping type
對映(mapping)
對映是定義一個文件以及其所包含的欄位如何被儲存和索引的方法。
例如,用對映來定義以下內容:
- 哪些 string 型別的 field 應當被當成當成 full-text 欄位
- 哪些欄位應該是數值型別、日期型別或者是地理位置資訊
- 日期型別欄位的格式是怎麼樣的
- 是否文件的所有欄位都需要被索引到 _all 欄位
- 動態增加的 field 可以由使用者自定義的模板來控制其行為
對映型別(mapping types)
每個索引都有一個或多個對映型別(mapping type)來對索引內的文件進行邏輯分組(mapping type 就是平常所說的 type)。
每一個對映型別都包含以下內容:
1. 元資料欄位
元資料欄位用來自定義如何處理關聯文件的元資料。元資料欄位包括: _index, _type, _id, _source.
2. 欄位列表或屬性
每個對映型別都包含一個欄位列表或者是和該型別相關的一些屬性。
欄位資料型別(field datatypes)
每一個欄位,都屬於一種資料型別。
1. 基本資料型別
string, long, boolean, ip
2. JSON 分層資料型別
object, nested
3. 特殊型別
geo_point, geo_shape, completion
動態對映(dynamic mapping)
欄位及其對映型別不必在使用前事先定義好,這得益於動態對映的應用。
動態對映能夠根據文件索引過程來自動生成對映型別和欄位名。
動態對映規則可以用來定義新型別和新欄位的對映。
顯式對映(explicit mappings)
如果你比 ES 通過猜測來確定對映更加了解你的資料,那麼定義一個動態對映將會很有用。不過有時候你可能需要指定自己的顯式對映。
顯式對映可以在建立索引時候定義,或者用 mapping API 來為已有的索引新增對映型別或欄位。
對映更新(updating existing mappings)
對映支援更新,如果需要,必須重建索引並設定正確的 mapping ,而不是試圖去更新已有的 mapping。
欄位之間共享對映型別(fileds are shared across mapping types)
對映型別用來邏輯分組欄位,但是每個對映型別之間的欄位並非獨立存在的。
1. 規則:
欄位在以下條件:
- 相同欄位名
- 相同索引
- 不同對映型別
的時候其實是對映到內部相同的欄位上,所以,必須擁有相同的對映設定。
2. 例外:
有一些例外,引數:
- copy_to
- dynamic
- enabled
- ignore_above
- include_in_all
- properties
可以對滿足前述“規則”的欄位進行各自不同的設定。
2 field datatypes
基本型別
1. 字串
字串型別被分為兩種情況:full-text 和 keywords。
full-text 表示欄位內容會被分析,而 keywords 表示欄位值只能作為一個精確值查詢。
引數:
analyzer
、boost
、doc_values
、fielddata
、fields
、ignore_above
、include_in_all
、index
、index_options
、norms
、null_value
、position_increment_gap
、store
、search_analyzer
、search_quote_analyzer
、similarity
、term_vector
2. 數值
數值型別包括: long, integer, short, byte, double, float 。
引數:
coerce
、boost
、doc_values
、ignore_malformed
、include_in_all
、index
、null_value
、precision_step
、store
3. 日期
JSON 本身並沒有日期資料型別,在 ES 中的日期型別可以是:
- 類似
"2015-01-01"
or"2015/01/01 12:10:30" 的字串
long 型別的毫秒級別的時間戳
int 型別的秒級別的時間戳
日期型別預設會被轉換為 UTC 並且轉換為毫秒級別的時間戳的 long 型別儲存。
日期型別如果不指定 format ,將會以預設格式表示。
引數:
boost
、doc_values
、format
、ignore_malformed
、include_in_all
、index
、null_value
、precision_step
、store
4. 布林
布林假: false
, "false"
, "off"
, "no"
, "0"
, ""
(empty string), 0
, 0.0 。
布林真: 任何不為假的值。
像 terms aggregation 聚合,是使用 1 和 0 來作為 key 的,key_as_string 則是用字串 true 和 false
布林型別的值,在 scripts 中則始終返回 1 或 0
引數:
boost
、doc_values
、index
、null_value
、store
5. 二進位制
二進位制型別以 Base64 編碼方式接收一個二進位制值,二進位制型別欄位預設不儲存,也不可搜尋。
引數:doc_values
、store
複雜型別
1. 物件
JSON 格式本身是分層級的——文件可以包含物件,物件還可以包含子物件。不過,在 ES 內部 "物件" 被索引為一個扁平的鍵值對。
例如:
PUT my_index/my_type/1
{
"region": "US",
"manager": {
"age": 30,
"name": {
"first": "John",
"last": "Smith"
}
}
}
轉換為:
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John",
"manager.name.last": "Smith" //層級結構被以 "." 來表示。
}
2. 陣列
陣列型別,要求陣列元素的資料型別必須一致。
- 字串陣列: [
"one"
,"two"
] - 數字陣列: [
1
,2
] - 陣列陣列: [
1
, [2
,3
]] which is the equivalent of [1
,2
,3
] - 物件陣列: [
{ "name": "Mary", "age": 12 }
,{ "name": "John", "age": 10 }
]
陣列元素的資料型別,將會由其第一個元素的資料型別決定。
物件陣列,在 ES 內部將會被轉換為 "多值" 的扁平資料型別。後面將會詳解這一點。
例如:
PUT my_index/my_type/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
轉轉為:
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}
3. 物件陣列
物件陣列在 ES 內部,會把所有陣列元素(即物件)合併,物件中的每一個欄位被索引為一個 "多值" 欄位。
這將導致每個陣列元素(物件)內部的欄位關聯性丟失,解決的方法是使用 nested 型別。
例如:
PUT my_index/my_type/1
{
"region": "US",
"manager": {
"age": 30,
"name": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Bob",
"last": "Leo"
}
]
}
}
轉換為:
{
"region": "US",
"manager.age": 30,
"manager.name.first": "John Bob",
"manager.name.last": "Smith Leo"
}
// 如果我們搜尋:
"bool": {
"must": [
{ "match": { "manager.name.first": "John" }}, // John Smith
{ "match": { "manager.name.last": "Leo"}} // Bob Leo
]
}
//這將會導致導致文件被命中,顯然,John Smith 、Bob Leo 兩組欄位它們內在的關聯性都丟失了
引數:
dynamic
、enabled
、include_in_all
、properties
4. 巢狀(nested)
巢狀型別是一個特殊物件型別,巢狀型別允許對物件陣列的每一個元素(物件)相互獨立的進行查詢,也即他們不會被合併為一個物件。
巢狀型別的文件可以:
- 用
nested
查詢來查詢 - 用
nested
來分析以及reverse_nested
來聚合 - 用 nested sorting 來排序
- 用 nested inner hits 來檢索或高亮
例如:
PUT my_index/my_type/1
{
"region": "US",
"manager": {
"age": 30,
"name": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Bob",
"last": "Leo"
}
]
}
}
轉換為:
{
"region": "US",
"manager.age": 30,
{
"manager.name.first": "John",
"manager.name.last": "Smith"
},
{
"manager.name.first": "Bob",
"manager.name.last": "Leo"
}
}
// 如果我們搜尋:
"bool": {
"must": [
{ "match": { "manager.name.first": "John" }}, // John Smith
{ "match": { "manager.name.last": "Leo"}} // Bob Leo
]
}
//這樣的查詢將不能命中文件!!!
引數:
dynamic
、include_in_all
、properties
專有型別
1. IPV4型別
IPV4 資料型別其實質是個 long 型別,不過其能接收一個 IPV4 地址並且將他轉換為 long 型別存放。
引數:
boost
、doc_values
、include_in_all
、index
、null_value
、precision_step
、store
3 Meta-Fields
文件標識相關元資料欄位
_index
- 當執行多索引查詢時,可能需要新增特定的一些與文件有關聯的索引的子句。
- _index 欄位可以用在 term、terms 查詢,聚合(aggregations)操作,指令碼(script)操作以及用來排序(sort)。
GET 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']"
}
}
}
_type
- _type 可以用來讓針對具體 type 的搜尋更加快。
- _type 欄位可以用在 querys、aggregations、scripts 以及 sorting。
GET my_index/_search/type_*
{
"query": {
"terms": {
"_type": [ "type_1", "type_2" ]
}
},
"aggs": {
"types": {
"terms": {
"field": "_type",
"size": 10
}
}
},
"sort": [
{
"_type": {
"order": "desc"
}
}
],
"script_fields": {
"type": {
"script": "doc['_type']"
}
}
}
原始資訊相關元資料欄位
_source
欄位說明
- _source 欄位存放的是文件的原始 JSON 資訊
- _source 欄位不被 indexed ,不過被 stored ,所以可以通過 get 或 search 取得該欄位的值。
禁用_source欄位
- _source 欄位可以在 mapping 設定中禁用
- 如果禁用 _source 欄位將會有一些其它影響,比如:update API 將無法使用等等。
PUT tweets
{
"mappings": {
"tweet": {
"_source": {
"enabled": false
}
}
}
}
_source排除特定欄位
- 在 _source 的 mapping 設定中可以通過 includes 和 excludes 引數來包含或排除特定欄位
- 包含或排除的欄位,需要以 plain 格式的 field 名稱,名稱支援萬用字元。
PUT logs
{
"mappings": {
"event": {
"_source": {
"includes": [
"*.count",
"meta.*"
],
"excludes": [
"meta.description",
"meta.other.*"
]
}
}
}
}
索引操作相關元資料欄位
_all
欄位說明
- _all 欄位把其他所有欄位的內容儲存到一個大的字串中,不管其它欄位是什麼資料型別,在 _all 中都被當作字串處理。
- 每個 index 只有一個 _all 欄位。
- 該字串會被 analyzed 和 indexed,但不會 store(儲存)。可以被搜尋,但無法用來恢復。
- _all 欄位也和普通字串欄位一樣可以接收:analyzer、term_vectors、index_options 和 store 等引數。
- 生成 _all 欄位是有資源消耗的,會消耗 CPU 和 disk 儲存。
GET my_index/_search
{
"query": {
"match": {
"_all": "john smith 1970"
}
}
}
_all欄位查詢
- query_string 和 simple_query_string 查詢操作,預設就是查詢 _all 欄位,除非自己明確指定。
GET _search
{
"query": {
"query_string": {
"query": "john smith 1970"
}
}
}
禁用_all欄位
- _all 欄位可以在 mapping 設定中完全禁用,如果禁用,query_string 和 simple_query_string 查詢操作需要指定預設欄位才可用。
PUT my_index
{
"mappings": {
"my_type": {
"_all": {
"enabled": false
},
"properties": {
"content": {
"type": "string"
}
}
}
},
"settings": {
"index.query.default_field": "content"
},
}
_all排除特定欄位
- 欄位通過 mapping 設定可以通過 include_in_all 引數控制該欄位否包含在 _all 欄位。
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"date": {
"type": "date",
"include_in_all": false
}
}
}
}
}
_all欄位儲存
- _all 欄位可以通過引數 store 來設定其是否儲存。
PUT myindex
{
"mappings": {
"mytype": {
"_all": {
"store": true
}
}
}
}
_field_names
欄位說明
GET my_index/_search
{
"query": {
"terms": {
"_field_names": [ "title" ]
}
},
"aggs": {
"Field names": {
"terms": {
"field": "_field_names",
"size": 10
}
}
},
"script_fields": {
"Field names": {
"script": "doc['_field_names']"
}
}
}
路由相關元資料欄位
_parent
欄位說明
- 在同一個 index 中,可以通過設定 type 的父子關係來建立文件之間的父子關係。
- 父子 type 必須是不同的 type。
- 指定的 parent type 必須要是還不存在的,已存在的 type 不能作為其它 type 的 parent type。
- 父子關係的 doc 必須被索引到相同的 shard 上,子文件通過引數 parent 引數來作為其 routing 來保證索引到相同分片。
PUT my_index
{
"mappings": {
"my_parent": {},
"my_child": {
"_parent": {
"type": "my_parent"
}
}
}
}
_routing
- _routing 欄位用來確定文件索引的分片:shared_num = hash(routing) % num_primary_shards
- 預設的 _routing 是文件的 _id 或 _parent 的 ID。
- 通過 routing 引數可以自定義 _routing 的值。
GET my_index/_search
{
"query": {
"terms": {
"_routing": [ "user1" ]
}
},
"aggs": {
"Routing values": {
"terms": {
"field": "_routing",
"size": 10
}
}
},
"sort": [
{
"_routing": {
"order": "desc"
}
}
],
"script_fields": {
"Routing value": {
"script": "doc['_routing']"
}
}
}
4 mapping setting
mapping type
對映設定一般發生在:
1. 增加新的 index 的時候,新增 mapping type,對 fields 的對映進行設定
PUT twitter
{
"mappings": {
"tweet": {
"properties": {
"message": {
"type": "string"
}
}
}
}
}
2. 為 index 增加新的 mapping type,對 fields 的對映進行設定
PUT twitter/_mapping/user
{
"properties": {
"name": {
"type": "string"
}
}
}
3. 為已有 mapping type 增加新的 fields 對映設定
PUT twitter/_mapping/tweet
{
"properties": {
"user_name": {
"type": "string"
}
}
}
設定方式
1. 在 PUT 請求體中給出完整的 mapping 設定
PUT twitter
{
"mappings": { //mappings 物件,說明進行 mapping 設定
"tweet": { //指定 mapping type
"properties": { //指定 mapping type 的 properties 設定
"message": { //對欄位 message 的對映進行設定
"type": "string" //mapping 引數配置
}
}
}
}
}
增加 index 的時候,除了可以設定 mapping type,還可以對 index 進行設定,比如配置自定義 analyzer、索引分片個數設定等
PUT /my_index
{
"settings": {
"analysis": {
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
}
},
"mappings": {
"my_type": {
"properties": {
"text": {
"type": "string",
"analyzer": "autocomplete"
}
}
}
}
}
2. 在 PUT 請求 URI 中指定 type,並在請求體中給出 type 的各項設定
PUT twitter/_mapping/user
{
"properties": { //指定 mapping type 的 properties 設定
"name": { //對欄位 message 的對映進行設定
"type": "string" //mapping 引數配置
}
}
}
3. 一個完整的 mapping type 設定包括:Meta-fields 和 Fields 或者 properties 設定
PUT my_index
{
"mappings": {
"type_1": {
"properties": {...} //properties 設定
},
"type_2": {
"_all": { //meta-fields 設定
"enabled": false
},
"properties": {...}
}
}
}
5 dynamic mapping
概述
在使用 ES 的時,我們不需要事先定義好對映設定就可以直接向索引中匯入文件。ES 可以自動實現每個欄位的型別檢測,並進行 mapping 設定,這個過程就叫動態對映(dynamic mapping)。
動態對映可以通過以下設定來關閉。
PUT /_settings
{
"index.mapper.dynamic":false
}
動態對映的規則也可以自定義,有以下幾種我們可以自定義規則的應用場景:
- 預設對映(_default_ mapping)
- 欄位動態對映(dynamic field mapping)
- 動態模板(dynamic template)
- 索引模板(index template)
其中,前 3 個條件中都是針對特定 index 下的 type 進行設定,而條件 4 是針對所有滿足條件的 index 進行設定。
預設對映
預設對映通過把 mapping type 設定為 _default_ 來定義。
預設對映將會應用到該 index 下的任意新增 type 中。
預設對映可以在新增 index 時候設定,也可以建立 index 之後再通過 PUT mapping 介面進行設定。
PUT my_index
{
"mappings": {
"_default_": {
"_all": {
"enabled": false //預設對映禁用掉所有新增 type 的 _all 元資料欄位
}
},
"user": {},
"blogpost": {
"_all": {
"enabled": true //覆蓋 _default_ 的設定,啟用 _all 欄位
}
}
}
}
欄位動態對映
預設情況,發現新的欄位,ES 自動檢測其 datatype 並將其加入到 mapping type 中。
通過一些設定,我們可以控制欄位動態對映的方式,包括:日期型別檢測、數值型別檢測、自定義日期型別的格式等。
PUT my_index //禁用日期型別檢測
{
"mappings": {
"my_type": {
"date_detection": false
}
}
}
PUT my_index //自定義日期型別的格式
{
"mappings": {
"my_type": {
"dynamic_date_formats": ["MM/dd/yyyy"]
}
}
}
PUT my_index //啟用數值型別檢測
{
"mappings": {
"my_type": {
"numeric_detection": true
}
}
}
動態模板
動態模板將會根據條件判斷,應用到滿足條件的新增欄位上去。
應用條件包括:
- 用 match_mapping_type 來檢測新增欄位的資料型別是否滿足某種條件
- 用 match、unmatch 和 match_pattern 來判斷新增欄位的欄位名是否滿足某種條件
- 用 path_match 和 path_unmatch 來判斷新增欄位的完整路徑是否匹配某條件
動態模板以陣列的形式給出,陣列的每一個元素就是一個模板。每個模板都有各自的應用條件,一旦新增的欄位滿足某個模板,模板內容就會應用到該欄位上。
有兩個特殊的變數,在模板中可以運用:{name}、{dynamic_type}。前者表示原欄位的欄位名,後者標識原欄位被 ES 自動識別出來的資料型別。
"dynamic_templates": [ //陣列,每個元素都是一個動態模板
{
"my_template_name": { //動態模板名稱
... match conditions ... //應用條件判斷
"mapping": { ... } //對映設定
}
},
... //多個數組元素標識多個動態模板
]
PUT my_index
{
"mappings": {
"my_type": {
"dynamic_templates": [
{
"named_analyzers": {
"match_mapping_type": "string",
"match": "*",
"mapping": {
"type": "string",
"analyzer": "{name}"
}
}
},
{
"no_doc_values": {
"match_mapping_type":"*",
"mapping": {
"type": "{dynamic_type}",
"doc_values": false
}
}
}
]
}
}
}
索引模板
索引模板根據條件來判斷新建的索引(只應用到新建索引上)是否滿足某條件,並對其進行對映設定。
索引模板包含一些對索引的設定和對映設定。
在索引模板中有一個特殊變數可以運用:{index}。表示匹配上條件的原索引名稱。
PUT /_template/template_1
{
"template": "te*", //判斷條件,判斷哪些索引將應用該模板
"settings": { //索引設定
"number_of_shards": 1
},
"mappings": { //對映設定
"type1": {
"_source": {
"enabled": false
},
"properties": {
"host_name": {
"type": "string",
"index": "not_analyzed"
},
"created_at": {
"type": "date",
"format": "EEE MMM dd HH:mm:ss Z YYYY"
}
}
}
}
}
參照:https://www.cnblogs.com/licongyu/category/819588.html
更多請參照:
- 前言
- 一Field datatype欄位資料型別
- 二Meta-Fields元資料
- 三Mapping引數
- 1 analyzer
- 2 normalizer
- 3 boost
- 4 coerce
- 5 copy_to
- 6 doc_values
- 7 dynamic
- 8 enabled
- 9 fielddata
- 10 format
- 11 ignore_above
- 12 ignore_malformed
- 13 include_in_all
- 14 index
- 15 index_options
- 16 fields
- 17 norms
- 18 null_value
- 19 position_increment_gap
- 20 properties
- 21 search_analyzer
- 22 similarity
- 23 store
- 24 term_vector
- 四動態Mapping