ElasticSearch之映射常用操作


本文案例操作,建議先閱讀我之前的文章《ElasticSearch之安裝及基本操作API》

Mapping (映射)類似關系型數據庫中的表的結構定義。我們將數據以 JSON 格式存入到 ElasticSearch 中后,在搜索引擎中 JSON 字段映射對應的類型,這時需要 mapping 來定義內容的類型。

字段類型

JSON 數據類型映射到 ElasticSearch 定義的類型,常用的簡單類型有:

JSON類型 ElasticSearch 類型
文本類型 Text/Keyword
整數類型 long/integer
浮點類型 float/double
時間類型 date
布爾值 boolean
數組 Text/Keyword

上面要注意的是時間類型,JSON 中並沒有時間類型,這里主要指時間格式數據的類型。

定義映射

在關系型數據庫中,存儲數據之前,我們會先創建表結構,給字段指定一個存在的類型。同樣 ElasticSearch 在進行數據存儲前,也可以先定義好存儲數據的 Mapping 結構。
先定義一個簡單的 person Mapping:

上圖中就是一個 Mapping 的定義,如果是在 ElasticSearch7 之前,mappings 里還有 _type 屬性。

動態映射

當沒有事先定義好 Mapping,添加數據時,ElasticSearch 會自動根據字段進行換算出對應的類型,但是換算出來的類型並不一定是我們想要的字段類型,還是需要人為的干預進行修改成想要的 Mapping。

更新映射

使用 dynamic 控制映射是否可以被更新。

dynamic-true

設置 dynamic 為true是默認 dynamic 的默認值,新增字段數據可以寫入,同時也可以被索引,Mapping 結構也會被更新。

添加數據,同時多添加一個沒被定義的 gender 字段。

# 向 person 中添加數據
PUT person/_doc/1
{
  "uId": 1,
  "name": "ytao",
  "age": 18,
  "address": "廣東省珠海市",
  "birthday": "2020-01-15T12:00:00Z",
  "money": 108.2,
  "isStrong": true,
  "gender": "男"    # Mapping 中未定義的字段
}

添加成功,搜索 gender 字段:

查看 Mapping 結構:

新添加的字段值,在添加過程中 Mapping 已自動添加字段。

dynamic-false

設置 dynamic 為false時,新增字段數據可以寫入,不可以被索引,Mapping 結構會被更新。
同樣先將 dynamic 設置為 false,然后向里面添加數據,其他步驟和上面 true 操作一樣。定義 Mapping,添加數據。
搜索 gender 字段:

此時新增字段數據無法被索引,但數據可以寫入。

Mappnig 也不會添加新增的字段:

dynamic-strict

設置 dynamic 為strict時,從字面上意思也可以看出,對於動態映射是較嚴格的,新增字段數據不可以寫入,不可以被索引,Mapping 結構不會被更新。只能按照定義好的 Mapping 結構添加數據。
在添加新字段數據時,就馬上會拋出異常:

自動識別日期類型

上文中,當 dynamic 設置為 true 時,添加新字段數據自動識別類型更新 Mapping,如果是日期類型的話,我們是可以指定識別的類型。
指定 person 的 dynamic_date_formats 格式:

PUT person/_mapping
{
  "dynamic_date_formats": ["yyyy/MM/dd"]
}

這里是可以指定多個時間格式。
向 person 添加新數據,分別是 today 和 firstDate:

PUT person/_doc/2
{
  "today": "2020-01-15",
  "firstDate": "2020/01/15"
}

添加新字段數據后的 Mapping:

由於上面我們指定了時間格式為 yyyy/MM/dd 時是可以識別為時間格式,所以 today 字段的值為 yyyy-MM-dd 格式無法識別為時間類型,判為 text 類型。

多字段

Mapping 中可以定義 fields 多字段屬性,以滿足不同場景下的實現。比如 address 定義為 text 類型,fields 里面又有定義 keyword 類型,這里主要是區分兩個不同不同使用場景。

  • text 會建立分詞倒排索引,用於全文檢索。
  • keyword 不會建立分詞倒排索引,用於排序和聚合。

添加數據:

# 向 person 中添加數據
PUT person/_doc/1
{
  "uId": 1,
  "name": "ytao",
  "age": 18,
  "address": "廣東省珠海市",
  "birthday": "2020-01-15T12:00:00Z",
  "money": 108.2,
  "isStrong": true
}

查詢address數據。

查詢address.keyword數據。

通過keyword檢索時,由於不會建立分詞索引,並沒有獲取到數據。

控制索引

在字段中使用 index 指定當前字段索引是否能被搜索到。指定類型為 boolean 類型,false 為不可搜索到,true 為可以搜索到。
先刪除之前的 Mapping:

DELETE person

創建 Mapping,設置name屬性的 index 為 false。

再次添加上面的數據后搜索name字段:

字段 index 設置 false 后,由於沒有被索引,所以搜索無法獲取到索引。

空值處理

現在向 ElasticSearch 中添加一條 address 為空的數據:

PUT person/_doc/2
{
  "uId": 2,
  "name": "Jack",
  "age": 22,
  "address": null,
  "birthday": "2020-01-15T12:00:00Z",
  "money": 68.7,
  "isStrong": true
}

搜索 address.keyword 為空的數據:

搜索返回異常,默認是不被允許搜索 NUll。
這是需要在 Mapping 指定 null_value 屬性,並且不能在text類型中聲明。

搜索 address.keyword 為空的數據:

設置 "null_value": "NULL" 后,空值可以處理搜索。

聚合多個字段

聚合多個字段放到一個索引中,使用 copy_to 進行聚合。例如我們在多字段查詢中,這是不需要對每個字段進行過濾篩選,只需對聚合字段即可。
在使用 copy_to 時,是通過指定聚合的名稱實現。

實際上,copy_to 不使用數組格式添加名稱,也會自動轉換成數據格式。

添加兩條數據,待校驗搜索:

# 向 person 中添加數據
PUT person/_doc/1
{
  "uId": 1,
  "name": "ytao",
  "age": 18,
  "address": "廣東省珠海市",
  "birthday": "2020-01-15T12:00:00Z",
  "money": 108.2,
  "isStrong": true
}

PUT person/_doc/2
{
  "uId": 2,
  "name": "楊廣東",
  "age": 22,
  "address": null,
  "birthday": "2020-01-15T12:00:00Z",
  "money": 68.7,
  "isStrong": true
}

查詢 full_name 的值,會返回 name 和 address 相關的值的對象。

從上面返回結果看到,_source 中的字段沒有增加相應的 copy_to 字段名,所以 copy_to 只會拷貝字段內容至索引,並不會改變包含的字段。

總結

通過本文對創建 Mapping 文件的常用並且實用的操作介紹,也基本能掌握這些日常的使用。了解 Mapping 的功能操作,相信對存儲時的設計也有一定幫助。

個人博客: https://ytao.top
關注公眾號 【ytao】,更多原創好文
我的公眾號


免責聲明!

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



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