ElasticSearch7.3 學習之Mapping核心資料型別及dynamic mapping

|舊市拾荒|發表於2022-03-19

1、mapping的核心資料型別以及dynamic mapping

1.1 核心的資料型別

string :text and keyword,byte,short,integer,long,float,double,boolean,date

詳見:https://www.elastic.co/guide/en/elasticsearch/reference/7.3/mapping-types.html

下圖是ES7.3核心的欄位型別如下:

1.2 dynamic mapping 推測規則

true or false --> boolean

123 --> long

123.45 --> double

2019-01-01 --> date

"hello world" --> text/keywod

1.3 檢視索引mapping

語法如下:

GET index_name/_mapping

2、手動管理mapping

2.1 查詢所有索引的對映

語法如下:

GET /_mapping

結果如下:

2.2 建立對映 

首先建立索引

PUT book

結果如下

建立索引後,應該立即手動建立對映

PUT book/_mapping
{
    "properties": {
           "name": {
                  "type": "text"
            },
           "description": {
              "type": "text",
              "analyzer":"english",
              "search_analyzer":"english"
           },
           "pic":{
             "type":"text",
             "index":false
           },
           "studymodel":{
             "type":"text"
           }
    }
}

結果如下:

2.3 欄位解釋 

2.3.1 Text 文字型別

1)analyzer:通過analyzer屬性指定分詞器。上邊指定了analyzer是指在索引和搜尋都使用english,如果單獨想定義搜尋時使用的分詞器則可以通過search_analyzer屬性。

2)index:index屬性指定是否索引。預設為index=true,即要進行索引,只有進行索引才可以從索引庫搜尋到。但是也有一些內容不需要索引,比如:商品圖片地址只被用來展示圖片,不進行搜尋圖片,此時可以將index設定為false。刪除索引,重新建立對映,將pic的index設定為false,嘗試根據pic去搜尋,結果搜尋不到資料。

3)store:是否在source之外儲存,每個文件索引後會在 ES中儲存一份原始文件,存放在"_source"中,一般情況下不需要設定store為true,因為在_source中已經有一份原始文件了。

舉個例子,插入以下文件:

PUT /book/_doc/1
{
  "name":"Bootstrap開發框架",
  "description":"Bootstrap是由Twitter推出的一個前臺頁面開發框架,在行業之中使用較為廣泛。此開發框架包含了大量的CSS、JS程式程式碼,可以幫助開發者(尤其是不擅長頁面開發的程式人員)輕鬆的實現一個不受瀏覽器限制的精美介面效果。",
  "pic":"group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg",
  "studymodel":"201002"
}

結果如下:

分別用以下語句來判斷是否

GET /book/_search?q=name:開發
GET /book/_search?q=description:開發
GET /book/_search?q=pic:group1/M00/00/01/wKhlQFqO4MmAOP53AAAcwDwm6SU490.jpg
GET /book/_search?q=studymodel:201002

通過測試發現:除了第三條語句,其餘均能搜尋出結果。也就是說name、description及studymodel都支援全文檢索,除了pic不可作為查詢條件。

2.3.2 keyword關鍵字欄位

目前已經取代了"index": false。上邊介紹的text文字欄位在對映時要設定分詞器,keyword欄位為關鍵字欄位,通常搜尋keyword是按照整體搜尋,所以建立keyword欄位的索引時是不進行分詞的,比如:郵政編碼、手機號碼、身份證等。keyword欄位通常用於過慮、排序、聚合等。

2.3.3 date日期型別

日期型別不用設定分詞器。

通常日期型別的欄位用於排序。

format:通過format設定日期格式

例子:下邊的設定允許date欄位儲存年月日時分秒、年月日及毫秒三種格式。

{
  "properties": {
    "timestamp": {
      "type": "date",
      "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
    }
  }
}

2.3.4 數值型別

下邊是ES支援的數值型別

在選擇資料型別的是,應儘量遵循下面的規範:

1、儘量選擇範圍小的型別,提高搜尋效率

2、對於浮點數儘量用比例因子,比如一個價格欄位,單位為元,我們將比例因子設定為100。這在ES中會按 分 儲存,對映如下:

"price": {
        "type": "scaled_float",
        "scaling_factor": 100
  },

由於比例因子為100,如果我們輸入的價格是23.45。則ES中會將23.45乘以100儲存在ES中。如果輸入的價格是23.456,ES會將23.456乘以100再取一個接近原始值的數,得出2346。使用比例因子的好處是整型比浮點型更易壓縮,節省磁碟空間。如果比例因子不適合,則從表中選擇範圍小的去用:

2.4 修改對映

只能建立index時手動建立mapping,或者新增field mapping,但是不能update field mapping。因為已有資料按照對映早已分詞儲存好,如果修改的話,那這些存量資料怎麼辦。

新增一個欄位mapping

PUT /book/_mapping/
{
  "properties": {
    "new_field": {
      "type": "text",
      "index": "false"
    }
  }
}

結果如下:

如果直接修改mapping的話會報錯

PUT /book/_mapping/
{
  "properties" : {
    "studymodel" : {
     "type" :    "keyword"
    }
  }
}

返回:

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "mapper [studymodel] of different type, current_type [text], merged_type [keyword]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "mapper [studymodel] of different type, current_type [text], merged_type [keyword]"
  },
  "status": 400
}

2.5 刪除對映

通過刪除索引的方式來刪除對映。

DELETE /book

3、複雜資料型別

3.1 multivalue field

如下所示,欄位裡面存放的是陣列

{ "tags": [ "tag1", "tag2" ]}

建立索引時與string是一樣的,注意陣列裡面存放的資料的資料型別不能混

3.2 empty field

空值存放

null,[],[null]

如果是text或者keyword型別,空值為null,如果是陣列型別的話,空值為後面兩個中的任意一個。

3.3 object field

意思就是欄位裡面存放的是一個物件

PUT /company/_doc/1
{
  "address": {
    "country": "china",
    "province": "guangdong",
    "city": "guangzhou"
  },
  "name": "jack",
  "age": 27,
  "join_date": "2019-01-01"
}

執行上面語句:

其中的address field 就是object型別

查詢company對映

GET /company/_mapping

返回:

{
  "company" : {
    "mappings" : {
      "properties" : {
        "address" : {
          "properties" : {
            "city" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "country" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "province" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        },
        "age" : {
          "type" : "long"
        },
        "join_date" : {
          "type" : "date"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

3.4 底層儲存格式

object型別:

{
  "address": {
    "country": "china",
    "province": "guangdong",
    "city": "guangzhou"
  },
  "name": "jack",
  "age": 27,
  "join_date": "2017-01-01"
}

對應的底層儲存格式,可以看到其實就是扁平化處理了

{
    "name":            [jack],
    "age":          [27],
    "join_date":      [2017-01-01],
    "address.country":         [china],
    "address.province":   [guangdong],
    "address.city":  [guangzhou]
}

物件陣列:

{
    "authors": [
        { "age": 26, "name": "Jack White"},
        { "age": 55, "name": "Tom Jones"},
        { "age": 39, "name": "Kitty Smith"}
    ]
}

儲存格式:

{
    "authors.age":    [26, 55, 39],
    "authors.name":   [jack, white, tom, jones, kitty, smith]
}

 

相關文章