通常情況下,我們使用ES建立索引的步驟是,先創建索引,然后定義索引中的字段以及映射的類型,然后再向索引中導入數據。而動態映射是ES中一個非常重要的概念,你可以直接向文檔中導入一條數據,與此同時,索引、字段、字段類型都會自動創建,無需你做其他的操作。這就是動態映射的神奇之處。
動態字段映射
ES的動態映射默認是開啟的,動態映射的默認規則如下:
JSON的數據類型 | ES中的數據類型 |
---|---|
null | 不會映射字段 |
true 或 false | boolean類型 |
浮點型數字 | float |
整型數字 | long |
JSON對象 | Object |
數組 | 第一個非空值得類型 |
String | 1、如果滿足日期類型的格式,映射為日期類型 |
2、如果滿足數字型的格式,映射為long或者float | |
3、如果就是字符串,會映射為一個text類型和一個keyword類型 |
接下來我們看看動態映射的一個例子,我們直接向dynamic-index
索引中存放一條數據,注意,dynamic-index
這個索引我們沒有創建過,直接存放數據,索引會自動創建。接下來,我們看一下具體的請求:
PUT /dynamic-index/_doc/1
{
"my_null": null,
"my_boolean": false,
"my_float": 1.56,
"my_long": 3,
"my_object": {
"my_first": "first value",
"my_second": "second_value"
},
"my_array": [1,2,3],
"my_date_1": "2020-05-01",
"my_date_2": "2020/05/01 12:03:03",
"my_date_3": "05/01/2020",
"my_string_long": "1",
"my_string_float": "4.6",
"my_string": "中華人民共和國"
}
請求執行成功以后,我們先看一下索引的類型:
GET /dynamic-index/_mapping
返回的結果如下:
{
"dynamic-index": {
"mappings": {
"properties": {
"my_array": {
"type": "long"
},
"my_boolean": {
"type": "boolean"
},
"my_date_1": {
"type": "date"
},
"my_date_2": {
"type": "date",
"format": "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
},
"my_date_3": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"my_float": {
"type": "float"
},
"my_long": {
"type": "long"
},
"my_object": {
"properties": {
"my_first": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"my_second": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"my_string": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"my_string_float": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"my_string_long": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
返回的結果比較長,我們把每一個字段都看一下,看看動態映射的字段是否達到了我們的預期:
字段 | 映射結果 | 是否達到預期 | 原因 |
---|---|---|---|
my_null | 沒有映射 | 是 | null值不映射 |
my_boolean | boolean | 是 | |
my_float | float | 是 | |
my_long | long | 是 | |
my_object | object | 是 | my_object里自動生成了兩個字段的映射 |
my_array | long | 是 | 數組中的數字是long型 |
my_date_1 | date | 是 | |
my_date_2 | date | 是 | |
my_date_3 | text | 否 | 沒有指定這種日期格式,所以映射為text |
my_string_long | text | 否 | 數字探測默認關閉,沒有打開 |
my_string_float | text | 否 | 數字探測默認關閉,沒有打開 |
my_string | text | 是 | 普通字符串,映射為text |
下面我們把數字探測打開,執行如下請求:
PUT /dynamic-index
{
"mappings": {
"numeric_detection": true
}
}
由於我們的索引dynamic-index
中,存在了映射關系,再進行設置是會報錯的,所以我們要將索引刪除,執行如下請求:
DELETE /dynamic-index
索引刪除成功后,再執行前面的設置,執行成功,數字探測已經打開。然后再添加一種日期格式MM/dd/yyyy
,請求如下:
PUT /dynamic-index
{
"mappings": {
"dynamic_date_formats": ["MM/dd/yyyy"]
}
}
執行報錯,錯誤信息和之前一樣,看來日期的設置要和數字探測一起才行,我們再將索引刪除,然后再發送請求,兩個設置一起:
PUT /dynamic-index
{
"mappings": {
"numeric_detection": true,
"dynamic_date_formats": ["MM/dd/yyyy"]
}
}
執行成功,我們再發送之前創建索引數據的請求
PUT /dynamic-index/_doc/1
{
"my_null": null,
"my_boolean": false,
"my_float": 1.56,
"my_long": 3,
"my_object": {
"my_first": "first value",
"my_second": "second_value"
},
"my_array": [1,2,3],
"my_date_1": "2020-05-01",
"my_date_2": "2020/05/01 12:03:03",
"my_date_3": "05/01/2020",
"my_string_long": "1",
"my_string_float": "4.6",
"my_string": "中華人民共和國"
}
執行成功,我們再看一下索引的映射,
"my_string_float": {
"type": "float"
},
"my_string_long": {
"type": "long"
}
"my_date_1": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"my_date_2": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"my_date_3": {
"type": "date",
"format": "MM/dd/yyyy"
},
我們重點看一下以上幾個字段,my_string_float
和my_string_long
映射成我們想要的類型了,由於我們開啟了數字探測。再看看我們映射的3個日期類型,咦?只有my_date_3
映射了日期類型,其他兩個都是映射成了text類型,這是由於我們在設置dynamic_date_formats
時,只指定了一種格式。我們只需要把其他兩種類型的日期格式也加上就可以了。
{
"mappings": {
"numeric_detection": true,
"dynamic_date_formats": ["MM/dd/yyyy","yyyy/MM/dd HH:mm:ss","yyyy-MM-dd"]
}
}
這里就不給大家具體演示了,有興趣的小伙伴去嘗試一下吧。
動態字段是ES中一個非常重要的功能,它給我們帶來了極大的方便,也省去了我們在開發時創建索引字段的時間,真是事半功倍,小伙伴們要好好掌握哦~~