ElasticSearch之映射經常使用操做

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

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

字段類型

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

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

上面要注意的是時間類型,JSON 中並無時間類型,這裏主要指時間格式數據的類型。app

定義映射

在關係型數據庫中,存儲數據以前,咱們會先建立表結構,給字段指定一個存在的類型。一樣 ElasticSearch 在進行數據存儲前,也能夠先定義好存儲數據的 Mapping 結構。 先定義一個簡單的 person Mapping:elasticsearch

上圖中就是一個 Mapping 的定義,若是是在 ElasticSearch7 以前,mappings 裏還有 _type 屬性。搜索引擎

動態映射

當沒有事先定義好 Mapping,添加數據時,ElasticSearch 會自動根據字段進行換算出對應的類型,可是換算出來的類型並不必定是咱們想要的字段類型,仍是須要人爲的干預進行修改爲想要的 Mapping。設計

更新映射

使用 dynamic 控制映射是否能夠被更新。3d

dynamic-true

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

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

# 向 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】,更多原創好文

個人公衆號

相關文章
相關標籤/搜索