【Elasticsearch 7 探索之路】(六)初識 Mapping


上一篇主要講解什么是 URL Search 和 Request Body Search 的語法。本篇對 Mapping 的 Dynamic Mapping 以及手動創建 Mapping 進行講解。

1.什么是 Mapping

  • Mapping 類似數據庫中的 schema 的定義,作用如下
    • 定義索引中的字段的名稱
    • 定義字段的數據類型,例如字符串,數值等
    • 字段,倒排索引的相關配置,比如可以通過配置字段是否需要被索引(Analyzed or Not Analyzed,Analyzer)
  • Mapping 會把 Json 文檔映射成 Lucene 所需要的扁平格式
  • 一個 Mapping 屬於一個索引的 Type,在 7.0 之后版本一個索引只有一個 Type(_doc)
    • 一個 Type 有一個 Mapping 定義
    • 7.0 開始,不需要在 Mapping 定義中指定 type 信息

2.常用字段的數據類型

  • 簡單類型
    • Text / Keyword
    • Date
    • Integer / float/ double /long
    • Boolean
    • Ip
  • 復雜類型-對象和嵌套對象
    • 對象類型/嵌套類型
  • 特殊類型(針對地理信息的有特殊處理)
    • geo_point & geo_shape / percolator

3.1什么是 Dynamic Mapping

Dynamic Mapping 會自動根據文檔信息,推算出字段的類型,使得你無需手動創建 Mapping。在寫入文檔時候,而且如果索引不存在,會自動創建索引。但是有時候推算也會錯誤,例如地理位置信息。當類型如果設置不對時,會導致一些功能無法正常運行,這點要特別注意。

下面總結 Json 類型到 Elasticsearch 類型的自動識別

3.2.Json 類型和 Elasticsearch 類型轉換映射

Json 類型 Elasticsearch 類型
字符串 1.匹配日期格式,轉為 Date
2.數值轉為 float 或者 long,默認關閉
3.轉為 Text,並且增加 keyword
布爾值 boolean
浮點數 float
整 數 long
對 象 Object
數 組 由第一個非空數值的類型所決定
空 值 忽略
PUT mapping_test/_doc/1
{
  "name":"al",
  "age":15,
  "ageStr":"15",
  "birth":"2019-12-18",
  "arg":["aaa","1"],
  "flag":false
}

GET mapping_test/_mapping

3.3.能否更改 Mapping 字段類型

  • 新增字段情況,Dynamic 設置為 true,帶有新字段的文檔寫入,Mapping 會更新。Dynamic 設置為 false,Mapping 不被更新,新增字段不會被索引。Dynamic 設置為 Strict,帶有新字段的文檔寫入會直接報錯。
  • 對已有字段並且存在數據情況,不支持修改字段定義,因為 ES 通過 Lucene 生成倒排索引,一旦生成就不許與修改
  • 如果實在需要修改可以通過 Reindex Api 重建索引
PUT mapping_test/_mapping
{
    "dynamic":"false"
}

PUT mapping_test/_doc/2
{
  "name":"al",
  "age":15,
  "ageStr":"15",
  "birth":"2019-12-18",
  "arg":["aaa","1"],
  "flag":false,
  "addCol":"test"
}

GET mapping_test/_search
{
  "query": {
    "match": {
      "addCol": "test"
    }
  }
}

當前設置 "dynamic":"false"時,新增的字段查詢不出結果。

4.1.手動創建 Mapping

上面我們介紹了關於 Dynamic Mapping 功能,現在但我們想要手動創建一個 Mapping 該如何創建。我先看一下下面代碼。

PUT student
{
    "mappings":{
      "properties": {
        "firstName":{
          "type":"text"
        },
        "lastName":{
          "type":"text"
        },
        "password":{
          "type":"text",
          "index":false
        }
    }
    }
}

PUT student/_doc/1
{
  "firstName":"AA",
  "lastName":"BB",
  "password":"abc"
}

POST student/_search
{
  "query": {
    "match_phrase": {
      "password": {
        "query": "abc"
      }
    }
  }
}

上面這個例子,就是一個比較簡單手動創建例子,我們通過為每一個字段創建類型,當指定 index:false 時,ES 將不對這個字段建立倒排索引,從上圖結果就可以看出。

4.2.Index Options

ES 有四種不同級別的 Index Options 配置

  • docs 記錄 doc id
  • freqs 記錄 doc id 和 term 頻次
  • positions 記錄 doc id 和 term 頻次 和 term 位置
  • offsets 記錄 doc id 和 term 頻次 和 term 位置和字符偏移量

Text 類型默認 positions,其他默認為 docs

4.3.copy_to

copy_to 是為瞞足一些特定搜素需求,將多個字段 數值拷貝到目標字段,目標字段不會出現在 _source。在 ES7 中,copy_to 已經替代 copy_to。例如下面這個例子,把 firsetName 和 lastName 合並一起搜素。

PUT student_1
{
    "mappings":{
      "properties": {
        "firstName":{
          "type":"text",
           "copy_to": "fullName"
        },
        "lastName":{
          "type":"text",
           "copy_to": "fullName"
        },
        "password":{
          "type":"text",
          "index":false
        }
    }
    }
}

PUT student_1/_doc/1
{
  "firstName":"AA",
  "lastName":"BB",
  "password":"abc"
}

Get student_1/_search?q=fullName:(AA BB)

5.小結

本篇主要對 Dynamic Mapping 以及手動創建 Mapping 進行講解,Dynamic Mapping 有好處也有壞處,好處我們無需定義 Mapping,壞處是推算的類型不一定正確,這點要留意。如果手動創建 Mapping 比較推薦先用 Dynamic Mapping 創建生成一個臨時索引,查詢 Mapping 定義(標題3.2 下面的結果圖)修改使用,這樣可以減少工作量和出錯的概率。

系列文章
【Elasticsearch 7 探索之路】(五)搜索相關 Search-API
【Elasticsearch 7 探索之路】(四)Analyzer 分析
【Elasticsearch 7 探索之路】(三)倒排索引
【Elasticsearch 7 探索之路】(二)文檔的 CRUD 和批量操作
【Elasticsearch 7 搜索之路】(一)什么是 Elasticsearch?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM