elasticsearch使用指南之Elasticsearch Dynamic Mapping(動態映射機制)

作者簡介:《RocketMQ技術內幕》作者、中間件興趣圈微信公衆號維護者

ElasticSearch Mapping(映射)目錄:
elasticsearch使用指南之Elasticsearch Mapping類型映射概述與元字段類型

Elasticsearch使用指南之Elasticsearch Mapping parameters(主要參數一覽)


Elasticsearch與關係型數據庫的另外一個不同就是索引下的的類型中的字段可以動態創建,無需在使用之前先創建好,支持在索引的過程中動態添加。這種機制也得意於Elasticsearch的動態映射機制,能根據字段的值動態猜測字段的類型,從而建立索引映射。
本節將重點介紹Elasticsearch動態映射機制。

PUT data/_doc/1 
{ "count": 5 }

執行上述請求時,索引"data"不必預先創建,該API會首先會自動創建索引data、類型映射_doc,其映射類型下包含字段count,其類型爲long。自動爲類型映射根據文檔的值推測其類型的過程,就是本文要重點描述的機制:動態類型映射機制。動態映射機制包含如下兩種映射規則:

  • Dynamic field mappings
  • Dynamic templates

接下來就分別介紹上述兩種動態映射規則。

1、Dynamic field mappings
動態字段映射規則。默認情況下,當在文檔中發現以前未見過的字段時,Elasticsearch將向類型映射添加新字段。通過將映射參數dynamic 設置爲false(忽略新字段)或strict(遇到未知字段時拋出異常),可以在文檔和對象級別禁用此行爲。

JSON datatype Elasticsearch datatype
null 不會自動增加類型映射
true or false boolean
floating point number float
integer long
object object
array 根據數組中第一個非空值來判斷
string date、double、long、text(帶有keyword子字段)

1.1 Date detection
日期類型檢測,如果啓用了date_detection(默認),那麼將檢查新字符串字段,以查看它們的內容是否匹配dynamic_date_format中指定的任何日期模式。如果匹配其中任意一種格式,則添加字段映射時,字段的類型爲date,並指定日期的format爲匹配的模式。例如:

PUT my_index/_doc/1
{
  "create_date": "2015/09/02"
}

則會爲create_date字段在json中的類型是字符串,但如果date_detection=true,則能映射爲date字段。
可以在類型_type級別設置是否開啓日期類型檢測(date_detection),示例如下:

PUT my_index
{
  "mappings": {
    "_doc": {
      "date_detection": false
    }
  }
}

1.2 定製日期類型檢測格式
可以通過類型級別(_type)級別通過dynamic_date_formats參數來自定義日期檢測格式,示例如下:

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_date_formats": ["MM/dd/yyyy"]
    }
  }
}

PUT my_index/_doc/1
{
  "create_date": "09/25/2015"
}

1.3 numeric detection
數字類型檢測。同樣如果數字類型的值在JSON中是用字符串表示的話,如果開啓日期類型檢測,同樣在創建映射時會映射爲數字類型,而不是字符串類型。

PUT my_index
{
  "mappings": {
    "_doc": {
      "numeric_detection": true
    }
  }
}

默認情況下,numeric_detection爲false。

2、Dynamic templates
Dynamic field mappings默認情況下是根據elasticsearch支持的數據類型來推測參數值的類型,而動態模板允許您定義自定義映射規則,根據自定義的規則來推測字段值所屬的類型,從而添加字段類型映射。
動態映射模板通過如下方式進行定義:

"dynamic_templates": [      // @1
    {
      "my_template_name": {    // @2
        ...  match conditions ...    // @3
        "mapping": { ... }              // @4
      }
    },
    ...
  ]

代碼@1:在類型映射時通過dynamic_templates屬性定義動態映射模板,其類型爲數組。
代碼@2:定義動態映射模板名稱。
代碼@3:匹配條件,其定義方式包括:match_mapping_type, match, match_pattern, unmatch, path_match, path_unmatch。
代碼@4:匹配@3的字段使用的類型映射定義(映射參數爲類型映射中支持的參數)

動態類型映射模板的核心關鍵是匹配條件與類型映射,接下來按照匹配條件定義方式來重點講解動態類型模板映射機制。

2.1、match_mapping_type
首先使用json解析器解析字段值的類型,由於JSON不能區分long和integer,也不允許區分double和float,所以它總是選擇更廣泛的數據類型, 例如5,在使用字段動態映射時,elasticsearch會將字段動態映射爲long而不是integer類型,那如何將數字5動態映射爲integer類型呢,利用match_mapping_type可以實現上述需求,例如,如果希望將所有整數字段映射爲整數而不是long,並將所有字符串字段映射爲文本和關鍵字,可以使用以下模板:

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "integers": {
            "match_mapping_type": "long",
            "mapping": {
              "type": "integer"
            }
          }
        },
        {
          "strings": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "fields": {
                "raw": {
                  "type":  "keyword",
                  "ignore_above": 256
                }
              }
            }
          }
        }
      ]
    }
  }
}

一言以蔽之,match_mapping_type爲字段動態映射(字段類型檢測)得出的類型建立一個映射關係,將該類型轉換爲mapping定義中的類型。

2.2、match and unmatch
match參數使用模式匹配字段名,而unmatch使用模式排除匹配匹配的字段。
match、unmatch示例如下:

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "longs_as_strings": {
            "match_mapping_type": "string",   // @1
            "match":   "long_*",                        // @2
            "unmatch": "*_text",                       // @3
            "mapping": {                                  // @4
              "type": "long"
            }
          }
        }
      ]
    }
  }
}
PUT my_index/_doc/1
{
  "long_num": "5",       // @5
  "long_text": "foo"      // @6
}

代碼@1:表示該自動映射模板針對的字段爲JSON解析器檢測字段的類型爲string的新增字段。
代碼@2:字段名稱以long_開頭的字段。
代碼@3:排除字段名稱以_text的字段。
代碼@4:符合long_開頭的字段,並且不是以_text結尾的字段,如果JSON檢測爲string類型的新字段,映射爲long。
代碼@5:long_num,映射類型爲long。
代碼@6:long_text雖然也滿足long_開頭,但是以_text結尾,故該字段不會映射爲long,而是保留其JSON檢測到的類型string,會映射爲text字段和keyword多字段(參考字段動態映射機制)。

2.3、match_pattern
使用正則表達式來匹配字段名稱。

"dynamic_templates": [
  {
    "longs_as_strings": {
       "match_mapping_type": "string",  
    "match_pattern": "regex",   // @1
       "match": "^profit_\d+$"       // @2
       "mapping": {                                  
           "type": "long"
        }
    }
  }
]

代碼@1:設置匹配模式爲regex代表java正則表達式
代碼@2:java正則表達式

2.4、path_match and path_unmatch
path_match與path_unmatch的工作方式與match、unmatch一樣,只不過path_match是針對字段的全路徑,特別是針對嵌套類型(object、nested)。
下面一個示例:將name下的字段除了middle字段爲copy到name屬性並列的full_name字段中。

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "copy_full_name": {
            "path_match":   "name.*",
            "path_unmatch": "*.middle",
            "mapping": {
              "type":       "text",
              "copy_to":    "full_name"
            }
          }
        }
      ]
    }
  }
}
PUT my_index/_doc/1
{
  "name": {
    "first":  "Alice",
    "middle": "Mary",
    "last":   "White"
  }
}

2.5、{name} and {dynamic_type}
{name}展位符,表示字段的名稱。
{dynamic_type}:JSON解析器解析到的字段類型。

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "named_analyzers": {                           // @1
            "match_mapping_type": "string",
            "match": "*",
            "mapping": {
              "type": "text",
              "analyzer": "{name}"
            }
          }
        },
        {
          "no_doc_values": {                         // @2
            "match_mapping_type":"*",
            "mapping": {
              "type": "{dynamic_type}",
              "doc_values": false
            }
          }
        }
      ]
    }
  }
}

PUT my_index/_doc/1
{
  "english": "Some English text", 
  "count":   5 
}

代碼@1:映射模板的含義爲:對所有匹配到的字符串類型,類型映射爲text,對應的分析器的名稱與字段名相同,這個在使用時慎重,可能不存在同名的分析器,本例只是一個展示。
代碼@2:對於匹配到的任何類型,其映射定義爲類型爲自動檢測的類型,並且禁用doc_values=false。

本節詳細介紹了Elasticsearch動態類型映射機制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章