elasticsearch之mapping詳解和數據類型
一、mapping介紹
- 類似數據庫中的表結構定義,主要作用如下:
- 定義 index 下的字段名(Field name)
- 定義字段的類型,比如 數值型,字符串型,布爾型等
- 定義倒排索引的相關配置,比如是的索引、是否記錄position 等
二、常用mapping 相關api
1、獲取索引 mapping
請求:GET XXX-INDEX/_mapping
響應:
{
"test": {
"mappings": {
"doc": {
"properties": {
"id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
三、自定義mapping
1、dynamic 參數
通過dynamic 參數可以控制字段的新增功能。
- true(默認)允許自動新增字段
- false不允許自動新增字段,但是文檔可以正常寫入,但是無法對字段進行查詢等操作
- strict文檔不能寫入,插入時會直接報錯
如:
1、設置 dynamic 參數
PUT test_index
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"user": {
"type": "text"
}
}
}
}
}
2、新增一條數據
PUT test_index/doc/1
{
"user": "qianmeng",
"age": 18 // 此字段是新增的,此時 dynamic是false,我們驗證其可插入但不可查詢的功能
}
3、查看mapping
GET test_index/_mapping
結果是:
{
"test_index": {
"mappings": {
"doc": {
"dynamic": "false",
"properties": {
"user": {
"type": "text"
}
}
}
}
}
}
此處第一次證明了dynamic參數的功能(可插入不可查詢)
4、查詢(試試是否真的不可查詢)
GET test_index/_search
{
"query": {
"match": {
"user": "qianmeng"
}
}
}
GET test_index/_search
{
"query": {
"match": {
"age": "18"
}
}
}
此處再次證明了 dynamic參數的功能,你會發現第一個查詢是無法查詢出來數據的,請自行驗證。strict類似,請自行驗證(strict不可插入,比false更加嚴格);
注:
- mapping 中的字段類型一旦設定後,禁止直接修改。原因是:Lucene 實現的倒排索引生成後不允許修改。
- 既然無法修改,或許我們需要重建索引,此時需要做索引數據遷移。es中提供了 reindex 可以幫助我們進行 索引間的數據遷移。
方式一:elasticsearch-migration
暫不支持join數據類型。
方式二:Logstash
input {
elasticsearch {
hosts => ["http://****:9200"]
index => "*"
docinfo => true
}
}
output {
elasticsearch {
hosts => ["http://****:9200"]
index => "%{[@metadata][_index]}"
}
}
方式三:Snapshot
前提:需要一個備份倉庫。啓動時創建,可在elasticsearch.yml中配置開啓。path.repo: [“/data/backups/elasticsearch”]
方式四:Reindex
第一步,關閉副本
PUT mytest/_settings
{
"number_of_replicas": 0
}
第二步,關閉自動更新
PUT mytest/_settings
{ "refresh_interval": -1 }
第三步,遷移數據
(1)集羣內索引間遷移數據
POST _reindex?slices=3&wait_for_completion=false
{
"source": {
"index": "applys", // 源索引
"size": 3000
},
"dest": {
"index": "twitter" // 目標索引
}
}
(2)跨集羣遷移數據
POST _reindex?slices=3&wait_for_completion=false
{
"source": {
"remote": {
"host": "http://****:9200"
},
"index": "test1",
"query": {
"match": {
"title": "elasticsearch"
}
}
},
"dest": {
"index": "test2"
}
}
注:slices大小=分片數,size大小需要調試(和elasticsearch環境以及索引情況有關);
wait_for_completion=false,此參數的含義是是否等待reindex 操作完成,當數據量較大時,我們無法長時間等待,所以這個參數我一般設置成false,這樣他會返回一個 taskid,我們可以根據taskid 查看reidnex 的進程和情況,對應命令是 GET _tasks/xxx-taskid;
此外,記住修改了副本數和刷新設置需要在遷移完成後及時恢復正常設置。
2、copy_to 參數
- 將該字段的值複製到目標字段,實現類型_all 的作用。
- 不會出現在 _source中,只用來搜索
例如:
3、index 參數
- 控制當前字段是否索引,默認爲true,即記錄索引, false 不記錄,即不可搜索
- 敏感字段常設置成 false,比如身份證,手機號碼等
- 調優可以查看此參數,將只存儲不參與搜索的字段設置爲 false,性能更好(節省了內存)
例如:
第一步,創建索引,並使用index 參數
PUT my_test
{
"mappings": {
"doc": {
"properties": {
"first_name": {
"type": "text",
"index": false
},
"last_name": {
"type": "text"
}
}
}
}
}
第二步,插入數據
PUT my_test/doc/1
{
"first_name": "John",
"last_name": "Smith"
}
第三步,查詢數據
GET my_test/doc/1
// 可以查出數據
GET my_test/_search
{
"query": {
"match": {
"last_name": "Smith"
}
}
}
// 不可以查出數據,報錯“Cannot search on field [first_name] since it is not indexed”(不可被索引)
GET my_test/_search
{
"query": {
"match": {
"first_name": "John"
}
}
}
4、index_options
(1)index_options 用於控制倒排索引的記錄內容,有如下4中設置:
- docs 只記錄 doc id
- freqs 記錄doc id 和 term frequencies(詞頻)
- positions 記錄doc id、term frequencies 和 term position
- offsets 記錄doc id、term frequencies 和 term position和 character offsets
(2)text 類型默認設置是 positions, 其他默認是 docs
(3)記錄內容越多,佔用空間就越大
例:
PUT my_test
{
"mappings": {
"doc": {
"properties": {
"first_name": {
"type": "text",
"index_options": "positions"
},
"last_name": {
"type": "text"
}
}
}
}
}
5、null_value
當字段遇到 null 值時的處理策略。默認爲null,即空值,此時es 會忽略該值,不保存。可以通過設定該值來設置字段的默認值
例:
PUT my_test
{
"mappings": {
"doc": {
"properties": {
"first_name": {
"type": "text"
},
"last_name": {
"type": "keyword",
"null_value": "haha"
}
}
}
}
}
四、數據類型
核心數據類型
- 字符串型:text(會分詞)、keyword(不會分詞)
- 數值型:long、integer、short、byte、double、float、half_float、scaled_float
- 日期類型:date
- 布爾類型:boolean
- 二進制類型:binary
- 範圍類型:integer_range、float_range、long_range、double_range、date_range
複雜數據類型
- 數組類型 array,默認會存儲成text
- 對象類型 object
- 嵌套類型 nested
地理位置數據類型
- geo_point
- geo_shape
專用數據類型
- 記錄ip地址 ip
- 實現自動補全 completion
- 記錄分詞數 token_count
- 記錄字符串hash值:murmur3
- 父子關係:join
補充:
(1)多字段特性 multi-fields
允許對同一個字段採用不同的配置,比如分詞,場景:如對人名實現拼音搜索,只需要在人名中新增一個子字段爲 pinyin 即可,如下:
PUT my_test
{
"mappings": {
"doc": {
"properties": {
"first_name": {
"type": "text",
"fields": {
"pinyin": { // 新增的子字段
"type": "text",
"analyzer": "pinyin" // 新增的分詞器
}
}
},
"last_name": {
"type": "keyword"
}
}
}
}
}
// 查詢如下
GET my_test/_search
{
"query": {
"match": {
"first_name.pinyin": "hanhan" // 子字段的查詢
}
}
}
五、自動識別字段類型
1、es是 靠 json 文檔的字段類型來實現自動識別字段類型,支持的類型如下:
JSON類型 | es類型 |
---|---|
null | 忽視 |
boolean | boolean |
浮點類型 | float |
整數 | long |
object | object |
array | 由第一個非 null 值的類型決定 |
string | 匹配爲日期則設爲 date類型;匹配爲數字則設爲float或long類型;設爲text類型,並附帶 keyword 的子字段。(從前到後以次匹配) |
2、日期的自動識別
- 日期的自動識別可以自行配置日期格式。
- 默認是[“strict_date_optional_time”, “yyyy/MM/dd HH:mm:ssZ||yyyy/MM/dd Z”]。
- dynamic_date_formats 可以自定義日期類型。
- date_detection 可以關閉日期自動識別的機制,此時保存的是text類型。
3、數字的自動識別
- 當字符串內容是數字時,默認不會自動識別成整形,因爲字符串中出現數字是合理的。
- numeric_datection 可以開啓字符串中數字的自動識別。
六、dynamic templates 動態模板
1、允許根據es 自動識別的數據類型、字段名等來動態設定字段類型,可以實現如下效果:
- 所有字符串類型都設定爲 keyword 類型,即默認不分詞
- 所有以 message 開頭的字段都設定爲 text 類型,即默認分詞
- 所有以 long_ 開頭的字段都設定爲 long 類型
- 所有自動匹配爲 double 類型的都設定爲 float 類型,以節省空間
例:
// 匹配 string 類型,並將其改成 keyword 類型
PUT test_index
{
"mappings": {
"docs": {
"dynamic_templates": [ // 數組,可指定多個匹配規則
{
"stringsHanle": { // template名稱,可自定義
"match_mapping_type": "string", // 匹配的規則,此處是匹配字符串類型
"mapping": { // 設置mapping 信息
"type": "keyword"
}
}
}
]
}
}
}
2、匹配規則
- match_mapping_type 匹配 es 自動識別的 字段類型,如 boolean、long、string等
- match,unmatch 匹配字段名
- path_match,path_unmatch 匹配路徑
例:
// 匹配 string 類型,匹配message開頭的,並將其改成 keyword 類型
PUT test_index
{
"mappings": {
"docs": {
"dynamic_templates": [ // 數組,可指定多個匹配規則
{
"stringsHanle": { // template名稱,可自定義
"match_mapping_type": "string", // 匹配的規則,此處是匹配字符串類型
"match": "message",
"mapping": { // 設置mapping 信息
"type": "text"
}
}
}
]
}
}
}
七、自定義mapping 的建議(個人)
自定義mapping的操作如下:
- 寫入一條文檔到es 中去,獲取es 自動生成的 mapping
- 修改獲取的 mapping,按需求自定義相關配置
- 使用修改後的 mapping 創建實際所需要的索引
八、索引模板
- index template,主要用於在新建索引 時自動應用預先設定的配置,簡化索引創建的操作步驟
- 可以設置索引的配置和mapping
- 可以有多個模板,根據order 設置,order 大的覆蓋小的配置
例:
PUT _template/test_template // template 名稱
{
"index_patterns": ["te*", "bar*"], // 匹配的 索引名稱,如te開頭
"order": 0, // order 順序設置
"settings": {
"number_of_shards": 1
},
"mapping": {
"doc": {
"properties": {
"name": {
"type": "text"
}
}
}
}
}
獲取與刪除索引模板
GET _template
GET _template/xxxx
DELETE _template/xxx