使用 dynamic_templates自定義動態索引
如果你想在執行時的增加新的欄位,你可能會開啟動態索引。雖然有時動態對映的 規則 顯得不那麼智慧,幸運的是我們可以通過設定來自定義這些規則。
當 Elasticsearch 遇到一個新的字串欄位時,它會檢測這個欄位是否包含一個可識別的日期,比如 2014-01-01。如果它看起來像一個日期,這個欄位會被作為 date 型別新增,否則,它會被作為 string 型別新增。
有些時候這個規則可能導致一些問題。想象你有一個文件長這樣:
{ "note": "2014-01-01" }
假設這是第一次見到 note 欄位,它會被新增為 date 欄位,但是如果下一個文件像這樣:
{ "note": "Logged out" }
這顯然不是一個日期,但為時已晚。這個欄位已經被新增為日期型別,這個 不合法的日期 將引發異常。
日期檢測可以通過在根物件上設定 date_detection 為 false 來關閉:
PUT /my_index
{
"mappings": {
"my_type": {
"date_detection": false
}
}
}
使用這個對映,字串將始終是 string 型別。假如你需要一個 date 欄位,你得手動新增它。
提示:
Elasticsearch 判斷字串為日期的規則可以通過 dynamic_date_formats 配置 來修改。比如在default mapping中配置:
"mappings": {
"_default_": {
"_all": {"enabled": false},
"dynamic_date_formats": ["yyyy-MM-dd HH:mm:ss"]
}
}
此時只有當字串格式為"yyyy-MM-dd HH:mm:ss"才會被自動識別為日期型別,並且format就是被識別的格式.
使用 dynamic_templates,你可以完全控制新欄位的對映,你設定可以通過欄位名或資料型別應用一個完全不同的對映。
每個模板都有一個名字用於描述這個模板的用途,一個 mapping 欄位用於指明這個對映怎麼使用,和至少一個引數(例如 match)來定義這個模板適用於哪個欄位。
模板按照順序來檢測,第一個匹配的模板會被啟用。例如,我們給 string 型別欄位定義兩個模板:
es: 欄位名以 _es 結尾需要使用 spanish 分析器。
en: 所有其他欄位使用 english 分析器。
我們將 es 模板放在第一位,因為它比匹配所有字串的 en 模板更特殊一點
PUT /my_index
{
"mappings": {
"my_type": {
"dynamic_templates": [
{ "es": {
"match": "*_es", <1>
"match_mapping_type": "string",
"mapping": {
"type": "string",
"analyzer": "spanish"
}
}},
{ "en": {
"match": "*", <2>
"match_mapping_type": "string",
"mapping": {
"type": "string",
"analyzer": "english"
}
}}
]
}}}
<1> 匹配欄位名以 _es 結尾的欄位.
<2> 匹配所有字串型別欄位。
match_mapping_type 允許你限制模板只能使用在特定的型別上,就像由標準動態對映規則檢測的一樣,(例如 strong 和 long)
match 引數只匹配欄位名,path_match 引數則匹配欄位在一個物件中的完整路徑,所以 address.*.name 規則將匹配一個這樣的欄位:
{
"address": {
"city": {
"name": "New York"
}
}
}
unmatch 和 path_unmatch 規則將用於排除未被匹配的欄位。
另一個例子:
"mappings": {
"_default_": {
"_all": {"enabled": false},
"dynamic_date_formats": ["yyyy-MM-dd HH:mm:ss"],
"dynamic_templates" : [
{
"strings" : {
"match" : "*",
"match_mapping_type": "string",
"mapping" : {
"type" : "string",
"index" : "no"
}
}
}
]
}
}
指定所有自動mapping的string型別的欄位的index都為no,即不索引欄位。