Elasticsearch的Mapping,定義了索引的結構,相似於關係型數據庫的Schema。Elasticsearch的Setting定義中定義分片和副本數以及搜索的最關鍵組件,即:Analyzer,也就是分析器。php
1、Dynamic Mapping及經常使用字段類型
mapping 的定義
Mapping相似於關係型數據庫的Schema,主要包含如下內容:html
- 定義索引中字段的名稱
- 定義字段的數據類型,如:字符串、數字、boolean等
- 可對字段設置倒排索引的相關配置,如是否須要分詞,使用什麼分詞器
從7.x開始,一個Mapping只屬於一個索引的typepython
- 每一個文檔屬於一個type
- 一個type有且僅有一個Mapping定義
- 從7.x開始,不須要在Mapping中指定type信息,默認type爲
_doc
經常使用字段類型
在Elasticsearch中,字段數據類型有如下經常使用的類型:sql
- 簡單類型
- Text / Keyword - 文本 / 關鍵字
- Date - 日期
- Integer / Float - 數字 / 浮點
- Boolean - 布爾值
- IPv4 / IPv6 - ip地址
- 複雜類型,包括對象和數組
- 對象
- 數組
- 特殊類型,如地理信息
- geo_point / ...
Dynamic Mapping
Dynamic Mapping 翻譯爲動態Mapping:數據庫
- 在寫入文檔時,若是索引不存在,會自動建立索引
- 這種機制,使得咱們無需手動定義mappings。Elasticsearch會自動根據文檔信息,推算出字段的類型
- 有的時候,Elasticsearch可能會推算不對,如:地理位置信息
- 當類型推算得不對時,可能致使一些功能沒法正常運行,如Range查詢。
經常使用類型的自動識別規則swift
類型 | 規則 |
---|---|
字符串 | 匹配到日期格式,設置成Date。 字符串爲數字時,當成字符串處理,但咱們設置轉換爲數字。 其餘狀況,類型就是Text,而且會增長keyword的子字段 |
布爾值 | Boolean |
浮點數 | Float |
整數 | Long |
對象 | Object |
數組 | 由第一個非空數值的類型決定 |
空值 | 忽略 |
下面是具體推斷 demoapi
# 寫入文檔,查看 Mapping PUT mapping_test/_doc/ 1 { "firstName": "Chan", -- Text "lastName": "Jackie", -- Text "loginDate": "2018-07-24T10:29:48.103Z" -- Date } # Dynamic Mapping,推斷字段的類型 PUT mapping_test/_doc/ 1 { "uid": "123", -- Text "isVip": false, -- Boolean "isAdmin": "true", -- Text "age": 19, -- Long "heigh": 180 -- Long } # 查看 Dynamic Mapping GET mapping_test/_mapping
可否更改mapping的字段類型
分兩種狀況:數組
一、新增長的字段app
- dynamic設爲true時,新增字段的文檔寫入時,Mapping同時被更新
- dynamic設爲false時,Mapping不會被更新,新增字段的數據沒法被索引,可是會出如今_source中
- dynamic設爲strict,文檔將寫入失敗
二、已存在的字段,一旦數據被寫入,就再也不支持修改字段定義學習
- Lucene自己的限制
- 若是但願更改字段類型,必須Reindex api,即:重建索引。在數據量多的時候,開銷將很是大
# dynamic設置爲 false PUT idx1 { "mapping": { "_doc": { "dynamic": "false" } } } # 修改成 dynamic爲 false PUT idx1/_mapping { "dynamic": false } # 查看索引 GET idx1/_mapping
dynamic屬性和索引字段可變性的規則,咱們能夠總結以下:
\ | true | false | strict |
---|---|---|---|
文檔可索引 | yes | yes | no |
字段可索引 | yes | no | no |
Mapping被更新 | yes | no | no |
顯式Mapping及常見參數
在本文的上一段落,咱們的Mapping都是自動生成的。自動生成機制雖然方便,可是也可能致使一些問題。好比:生成的字段類型不正確,字段的附加屬性不知足咱們的需求,等等。這時,咱們能夠經過顯式Mapping的方式來解決。
那麼,咱們如何進行顯式Mapping的設置呢?
- 參考官網api,純手寫
- 爲減小工做量,減小出錯機率,可以下進行:
- 建立一個臨時index,寫入一些樣本數據
- 經過訪問Mapping API獲取該臨時文件的動態Mapping定義
- 修改後,再使用此配置建立本身的索引
- 刪除臨時索引
咱們推薦使用第二種方式,效率高,且不容易出錯。
控制當前字段是否被索引———index
index,可用於設置字段是否被索引,默認爲true,false即爲不可搜索。在下述例子中,mobile字段將不能被搜索到。
# index屬性控制 字段是否能夠被索引 PUT user_test { "mappings": { "properties": { "firstName":{ "type": "text" }, "lastName":{ "type": "text" }, "mobile" :{ "type": "text", "index": false } } } }
常見參數 - index_options
記錄索引級別。Text類型默認爲positions,其餘類型默認爲docs。咱們須要記住一條準則。
記錄的內容越多,佔用的存儲空間就越大。
索引級別有如下幾種,更細節的內容可參考官網
- docs
- freqs
- positions
- offsets
null_value設置
須要對Null值實現搜索時使用。只有keyword類型才支持設定null_value
# 設定Null_value DELETE users PUT users { "mappings" : { "properties" : { "firstName" : { "type" : "text" }, "lastName" : { "type" : "text" }, "mobile" : { "type" : "keyword", "null_value": "NULL" } } } } PUT users/_doc/ 1 { "firstName": "Zhang", "lastName": "Fubing", "mobile": null } PUT users/_doc/ 2 { "firstName": "Zhang", "lastName": "Fubing2" } # 查看結果,有且僅有_id爲2的記錄 GET users/_search { "query": { "match": { "mobile": "NULL" } } }
copy_to
這個屬性用於將當前字段拷貝到指定字段。
_all
在7.x版本已經被copy_to
所代替- 可用於知足特定場景
copy_to
將字段數值拷貝到目標字段,實現相似_all
的做用copy_to
的目標字段不出如今_source中
DELETE user_test #設置 Copy to PUT user_test { "mappings": { "properties": { "firstName":{ "type": "text", "copy_to": "fullName" }, "lastName":{ "type": "text", "copy_to": "fullName" } } } } PUT user_test/_doc/ 1 { "firstName": "Ruan", "lastName": "Yiming" } POST user_test/_search?q=fullName:(Ruan Yiming)
數組類型
Elasticsearch不提供專門的數組類型。但任何字段,均可以包含多個相同類型的數值。
# 數組類型 PUT users/_doc/ 1 { "name": "onebird", "interests": "reading" } PUT users/_doc/ 1 { "name": "twobirds", "interests":[ "reading", "music"] } POST users/_search { "query": { "match_all": {} } } # interests字段仍是text類型 GET users/_mapping