本文案例操做,建議先閱讀我以前的文章《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 的默認值,新增字段數據能夠寫入,同時也能夠被索引,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
時,新增字段數據能夠寫入,不能夠被索引,Mapping 結構會被更新。 一樣先將 dynamic 設置爲 false,而後向裏面添加數據,其餘步驟和上面 true 操做同樣。定義 Mapping,添加數據。 搜索 gender
字段:
此時新增字段數據沒法被索引,但數據能夠寫入。
Mappnig 也不會添加新增的字段:
設置 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】,更多原創好文