Elasticsearch入門教程(三):Elasticsearch索引&映射

原文: Elasticsearch入門教程(三):Elasticsearch索引&映射

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接: https://blog.csdn.net/vbirdbest/article/details/79213163

索引概念簡介

一般說的索引有兩種詞性,名稱和動詞。git

  • 動詞索引indexing,索引一個文檔,表示把一個文檔存儲到索引Index裏,能夠用來查詢和檢索,es採用倒排索引
  • 名詞索引index,簡單的理解成關係型數據庫中的數據庫的概念

索引的命名必須是所有小寫,不能如下劃線開頭.github

建立索引

建立索引能夠顯式建立,也能夠隱式建立。算法

  • 顯式建立:在關係型數據庫中,須要先建數據庫,在建立數據庫時能夠指定一些配置,如字符編碼,數據庫引擎等,建立表時須要指定表都包含哪些列,每一個列的數據類型等,在在Elasticsearch中建立數據庫(索引)和建立表(映射)是一步完成的,顯式建立須要在建立時指定對索引的一些配置,須要列舉出索引包含的字段,也就是所謂的映射Mapping
  • 隱式操做:隱式操做的方式是直接向索引中插入一條文檔便可,es在插入的時候會判斷索引是否存在,若是不存在,系統會根據文檔包含的字段做爲索引的映射,對索引的一些配置採用默認的配置來建立出來索引,建立索引的過程是es在後臺默默的實現的。

顯式建立能夠根據具體狀況對索引進行配置,並且對於中文分詞es是默認採用的分詞是適合英文並適合中文的,能夠在建立索引的時候本身指定分詞器。sql

ES支持的數據類型

  • text 文本類型,text類型若是不顯示指定映射的字段屬性,默認是使用標準分詞器進行分詞,通常數據類型是text要麼顯示指定分詞器,要麼不分詞,通常不使用默認的分詞器(除非文本是純英文)
  • keyword : 若是數組中的值是字符串,最好使用keyword, 它不會對字符串進行分詞
  • date 支持的格式有:能夠經過format定義日期的數據格式,也支持毫秒數
  • boolean
  • float
  • double
  • byte
  • short
  • integer
  • long
  • object
  • nested : 嵌套對象, 用於數組中的元素是對象的[{}, {}]
  • ip 即支持ipv4也支持ipv6
  • completion
  • binary
  • geo-point: 支持經緯度存儲和距離範圍檢索
  • geo-shape:支持任意圖形範圍的檢索,例如矩形和平面多邊形

注意:不一樣的數據類型索引的方式有稍許不一樣,如date何text類型不同,date採用精確匹配,text採用全文檢索方式。對於數組,es並無專門的數組類型。任何域均可以包含0、1或者多個值,就像全文域分析獲得多個詞條。這暗示 數組中全部的值必須是相同數據類型的。數據庫

映射mappings

映射就是建立索引時指定都包含哪些字段以及字段的數據類型、分詞器等一些設置。數組

字段設置參數bash

  • 「type」: 「text」, // 指定字段的數據類型
  • 「analyzer」:」ik _max_word」, //指定分詞器的名稱,便可用使用內置的分詞器也可使用第三方分詞器
    • 默認standard,
    • 內置的分析器有whitespace 、 simple和english
    • 第三方分詞器:ik分詞器 包括ik_max_word和ik_smart,ik_max_word:會將文本作最細粒度的拆分;儘量多的拆分出詞語 ,ik_smart:會作最粗粒度的拆分;已被分出的詞語將不會再次被其它詞語佔有
  • 「search_analyzer」:」ik _max_word」 // 指定查詢的分詞器,默認和analyzer保持一致,通常分詞器和查詢分詞器要保持一致
  • 「properties」: {}, // 當數據類型是object時,須要具體指定內部對象對應的字段
  • 「format」: 「yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis」 // 格式化,通常用於指定日期類型的格式
  • 「dynamic」: 「strict」 動態映射配置,當文檔中發現新字段時應該如何處理, 能夠用在根 object 或任何 object 類型的字段上,你能夠將 dynamic 的默認值設置爲 strict , 而只在指定的內部對象中開啓它
    • true: 默認值,動態添加新的字段
    • false: 忽略新的字段
    • strict: 若是遇到新字段拋出異常,若是Elasticsearch是做爲重要的數據存儲,可能就會指望遇到新字段就會拋出異常,這樣能及時發現問題。
  • dynamic_templates 動態模板:爲知足條件的字段作統一映射,能夠經過字段名稱或者字段類型來匹配指定的映射規則,每一個模板都有一個名稱,你能夠用來描述這個模板的用途, 一個mapping來指定映射應該怎樣使用,以及至少一個參數 (如 match) 來定義這個模板適用於哪一個字段。
    模板按照順序來檢測;第一個匹配的模板會被啓用
    • match 參數只匹配字段名稱
    • match_mapping_type 容許你應用模板到特定類型的字段上,就像有標準動態映射規則檢測的同樣
  • 「fielddata」:boolean //針對分詞字段,參與排序或聚合時能提升性能,默認是false,false是不容許聚合操做的
  • 「boost」:1.23 // 權重:字段級別的分數加權,指定字段在搜索時所佔的權重,所佔的百分比
  • 「fields」:{「raw」:{「type」:」keyword」}} //能夠對一個字段提供多種索引模式,同一個字段的值,一個分詞,一個不分詞,應用場景:便可以用於對字符串進行字符排序,也能夠全文索引,排序時使用字段.raw來引用排序字段
  • 「index」: 「analyzed」, // 指定文本類型的字段是否分詞、是否存儲該字段的值(在新版本中index值爲boolean類型,語意也發生了變化,TODO待更新),有三個值:
    • analyzed:首先分析字符串,而後索引(存儲)它。換句話說,以全文索引這個域(也就是說即分詞,又存儲字段的值,便可以經過全文檢索的方式對該字段進行搜索)
    • not_analyzed:索引(存儲)這個域,因此它可以被搜索,但索引的是精確值。不會對它進行分析(不對字段的值進行分詞,而是完整的存儲該值,因此只能經過精確值才能搜索出來,即徹底匹配,至關於sql中的等號=的做用)
    • no:不索引這個域。這個域不會被搜索到(對該字段不分詞,也不存儲,至關於沒有這個字段同樣???)
  • 「store」:false//是否單獨設置此字段的是否存儲而從_source字段中分離,默認是false,只能搜索,不能獲取值
  • 「doc_values」:false//對not_analyzed字段,默認都是開啓,分詞字段不能使用,對排序和聚合能提高較大性能,節約內存
  • 「ignore_above」:100 //超過100個字符的文本,將會被忽略,不被索引
  • 「include_in_all」:ture//設置是否此字段包含在_all字段中,默認是true,除非index設置成no選項
  • 「index_options」:」docs」//4個可選參數docs(索引文檔號) ,freqs(文檔號+詞頻),positions(文檔號+詞頻+位置,一般用來距離查詢),offsets(文檔號+詞頻+位置+偏移量,一般被使用在高亮字段)分詞字段默認是position,其餘的默認是docs
  • 「norms」:{「enable」:true,」loading」:」lazy」}//分詞字段默認配置,不分詞字段:默認{「enable」:false},存儲長度因子和索引時boost,建議對須要參與評分字段使用 ,會額外增長內存消耗量
  • 「null_value」:」NULL」//設置一些缺失字段的初始化值,只有string可使用,分詞字段的null值也會被分詞
  • 「position_increament_gap」:0//影響距離查詢或近似查詢,能夠設置在多值字段的數據上火分詞字段上,查詢時可指定slop間隔,默認值是100
  • 「similarity」:」BM25」//默認是TF/IDF算法,指定一個字段評分策略,僅僅對字符串型和分詞類型有效
  • 「term_vector」:」no」//默認不存儲向量信息,支持參數yes(term存儲),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 對快速高亮fast vector highlighter能提高性能,但開啓又會加大索引體積,不適合大數據量用

ik分詞器 https://github.com/medcl/elasticsearch-analysis-ik 支持自定義熱詞配置(如 香菇 藍瘦 帥的一逼 等)微信

  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
// 默認standard,內置的分析器有whitespace 、 simple 和 english // ik支持兩種分詞器:ik_max_word,ik_smart // 分析器:用於測試分詞的數據 GET /_analyze { "analyzer" : "ik_max_word", "text": "美國留給伊拉克的是個爛攤子嗎" }

settings設置

settings用於設置索引的分片數量、副本數量、默認的分詞器等,Elasticsearch 提供了優化好的默認配置。 除非你理解這些配置的做用而且知道爲何要去修改,不然不要隨意修改。markdown

  • 「number_of_shards」 : 5, // 每一個索引的主分片數,默認值是 5 。這個配置在索引建立後不能修改。
  • 「number_of_replicas」 : 1, // 每一個主分片的副本數,默認值是 1 。對於活動的索引庫,這個配置能夠隨時修改。
  • 「analysis」 : { 「analyzer」 : { 「ik」 : { 「tokenizer」 : 「ik_ max_word」 } } }
  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
// 建立只有 一個主分片,沒有副本的小索引: PUT /my_temp_index { "settings": { "number_of_shards" : 1, "number_of_replicas" : 0 } } // 用update-index-settings API 動態修改副本數: PUT /my_temp_index/_settings { "number_of_replicas": 1 }

aliases別名

索引別名就像一個快捷方式或軟鏈接,或者是一個指向,都是最終指的同一個東西,別名 帶給咱們極大的靈活性,容許咱們作下面這些:app

  • 在運行的集羣中能夠無縫的從一個索引切換到另外一個索引
  • 給多個索引分組 (例如, last_three_months)
  • 給索引的一個子集建立 視圖

有兩種方式管理別名: _alias用於單個操做, _aliases用於執行多個原子級操做。

Mapping一旦建立是不容許修改字段的數據類型的,爲了防止之後有可能修改索引的狀況,剛開始建立索引時最好就爲該索引建立一個別名,而後在程序中直接使用別名,而不使用真實的索引名稱。
若是後面須要要修改映射,能夠再建立一個新的索引,而後把以前索引裏的數據導入到新建立的索引裏, 爲新索引增長一個別名,將別名從老索引中移除,這樣應用程序仍然使用的是別名,而這個別名已經指向了新的索引,這樣就達到了不修改索引名而修改索引的目的。

  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
// 0. 建立索引(age的類型爲long) PUT /school_v1 { "mappings": { "students": { "properties": { "name": { "type": "text" }, "age": {"type": "long"} } } } } // 1. 爲索引建立一個別名 PUT /school_v1/_alias/school // 查看別名指向的索引 GET /*/_alias/school // 查詢索引對應的別名 GET /school_v1/_alias/* // 2.建立一個新的索引,名字不能和以前的不同,此次將age的數據類型改成short PUT /school_v2 { "mappings": { "students": { "properties": { "name": { "type": "text" }, "age": {"type": "short"} } } } } // 3.遷移數據:將以前的索引裏的文檔遷移到新的索引上 // 先將數據批量查詢出來,而後批量插入 GET /school/students/_search?scroll=1m POST /schools/students/_bulk {"index": {"_id": 1}} {"name": "張三","age": 27} {"index": {"_id": 2}} {"name": "小明","age": 28} GET /schools/students/_search // 4.爲新索引增長別名,別名名稱爲老索引名稱,這樣系統能夠直接使用老索引的名稱來操做新索引 POST /_aliases { "actions": [ { "add": { "index": "school_v2", "alias": "school"}, "remove": { "index": "school_v1", "alias": "school"} } ] } GET /school/students/_search

別名就是索引的另外一個名字,就像人的姓名和筆名同樣,都是指向的同一我的,能夠經過POST /_aliases 路徑對別名進行add、remove操做

TIP: 在你的應用中使用別名而不是索引名。而後你就能夠在任什麼時候候重建索引。別名的開銷很小,應該普遍使用。

索引操做

建立索引
PUT /{index}

  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
// 注意:當前建立的索引的動態映射配置根對象是不容許添加新字段的,動態映射類型爲嚴格類型,可是內部對象是容許添加新字段的 PUT /shop_v1 { "aliases": { "shop": {} }, "settings" : { "number_of_shards" : 5, "number_of_replicas" : 1, "refresh_interval": "1s", "analysis" : { "analyzer" : { "ik" : { "tokenizer" : "ik_max_word" } } } }, "mappings": { "goods": { "dynamic": "strict", "dynamic_templates":[ { "date": { "match": "*_date", "match_mapping_type": "date", "mapping": { "type": "date", "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } }}, { "ik": { "match": "*", "match_mapping_type": "string", "mapping": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" } }} ], "properties": { "name": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" }, "price": { "type": "double" }, "quantity": { "type": "integer" }, "colors": { "type": "keyword" }, "is_discount": { "type": "boolean" }, "create_date": { "type": "date", "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" }, "ip_addr": { "type": "ip" }, "location": { "type": "geo_point", "lat_lon": true }, "merchant": { "type": "object", "dynamic": true, "properties": { "id": { "type": "long" }, "shop_name": { "type": "text" } } }, "cpu": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } }

refresh_interval:索引刷新時間間隔,一個持續時間值, 例如 1s(1 秒) 或 2m(2 分鐘)。 一個絕對值1表示的是1毫秒 –無疑會使你的集羣陷入癱瘓, -1:表示關閉刷新, 默認爲一秒,若是索引了一個文檔而後當即嘗試搜索它,但卻沒有搜到,多是尚未到間隔時間,尚未刷新

  • 查看全部索引 GET /_cat/indices?v&pretty

  • 查看某個索引 GET /{index}

  • 刪除索引單個索引 DELETE /{index}

  • 刪除全部索引 DELETE /_all 或者 DELETE /*

  • 刪除多個索引: DELETE /index1,index2 或者 DELETE /index*

  • 查看索引的映射 GET /{index}/_mapping

  • 查看某個索引的某個類型的映射 GET /{index}/_mapping/{type}

  • 映射添加新字段 PUT /{index}/_mapping/{type}

  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
PUT /shop/_mapping/goods { "properties": { "params": { "type": "nested", "properties": { "id": { "type": "long" }, "label": { "type": "text" }, "value": { "type": "text" } } } } }
  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
// 插入一條文檔 POST /shop/goods { "name": "【特別尺碼】女裝 棉混紡休閒針織衫(長袖) 407767 優衣庫UNIQLO", "price": 149.00, "quantity": 100, "colors": ["乳白色", "紅色", "黃色"], "is_discount": true, "create_date": "2018-01-31 12:10:30", "ip_addr": "192.168.1.1", "location": "41.12,-71.34", "merchant": { "id": 1111, "shop_name": "優衣庫官方旗艦店" }, "params": [ {"id": 1, "label":"貨號", "value": "7525001123"}, {"id": 2, "label":"品牌", "value": "Cache Cache"} ] }

查詢文檔 /{index}/{type}/_search

  
  
  
   
   
            
   
   
  • 1
GET /shop/goods/_search

修改索引

  • 新增字段
  • 修改字段的數據類型
  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
``` // 建立索引 PUT /school { "mappings": { "students": { "properties": { "name": { "type": "text" }, "age": {"type": "long"} } } } } // 插入一條文檔 PUT /school/students/1 { "name": "張三", "age": 27 } // 查詢映射 GET school/_mapping/students // 添加文檔,增長一個新字段height身高 PUT /school/students/2 { "name": "小明", "age": 28, "height": 1.80 } GET school/_mapping/students // 查看映射能夠看到自動將height做爲float類型添加到映射裏面 "height": {"type": "float"}

從新索引

儘管能夠增長新的類型到索引中,或者增長新的字段到類型中,可是不能添加新的分析器或者對現有的字段作改動。 若是你那麼作的話,結果就是那些已經被索引的數據就不正確, 搜索也不能正常工做。

對現有數據的這類改變最簡單的辦法就是從新索引:用新的設置建立新的索引並把文檔從舊的索引複製到新的索引。

爲了有效的從新索引全部在舊的索引中的文檔,用 scroll 從舊的索引檢索批量文檔 , 而後用 bulk API 把文檔推送到新的索引中。

同時並行運行多個重建索引任務,可是你顯然不但願結果有重疊。正確的作法是按日期或者時間 這樣的字段做爲過濾條件把大的重建索引分紅小的任務:

  
  
  
   
   
            
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
GET /old_index/_search?scroll=1m { "query": { "range": { "date": { "gte": "2014-01-01", "lt": "2014-02-01" } } }, "sort": ["_doc"], "size": 1000 }

若是舊的索引持續會有變化,你但願新的索引中也包括那些新加的文檔。那就能夠對新加的文檔作從新索引, 但仍是要用日期類字段過濾來匹配那些新加的文檔。

經過建立新的索引,將數據從新遷移到新索引中,這種變相的更改索引的配置的方式的缺點是改變了原索引的名稱(索引名稱不容許重複,新索引就要使用新的索引名)。

注意

  • 禁用_all或者通配符,防止誤操做
    對一些人來講,可以用單個命令來刪除全部數據可能會致使可怕的後果。若是你想要避免意外的大量刪除, 你能夠在你的 elasticsearch.yml 作以下配置:action.destructive_requires_name: true
    這個設置使刪除只限於特定名稱指向的數據, 而不容許經過指定 _all 或通配符來刪除指定索引庫。你一樣能夠經過 Cluster State API 動態的更新這個設置。

個人微信公衆號:

相關文章
相關標籤/搜索