ElasticSearch(提高篇)
前言
Elasticsearch
的簡單入門請參考之前寫的一篇文章Elasticsearch簡單入門篇,這篇簡單介紹啦Elasticsearch
的基本安裝、Docker
安裝方法、基本的概念,以及如何使用Java
程式碼實現對Elasticsearch
的CRUD
操作等入門知識。
內容摘要
1.1.Elastic Stack應用場景
- 網站搜尋、程式碼搜尋等(例如生產環境的日誌收集 ——格式化分析——全文檢索——系統預警)
- 日誌管理與分析、應用系統效能分析、安全指標監控等
1.2.Elastic Stack技術架構
Elastic static家族產品
高階架構
Elastic
的技術架構可以簡單,也可以高階,它是很具有擴充套件性的,最簡單的技術架構就是使用Beats
Beats
是一種抽象的稱呼,具體的可以是使用FileBeat
收集資料來源為檔案的資料或者使用TopBeat
來收集系統中的監控資訊,可以說類似Linux
系統中的TOP
命令,當然還有很多的Beats
的具體實現,再使用logstash
進行資料的轉換和匯入到Elasticsearch
中,最後使用Kibana
進行資料的操作以及資料的視覺化等操作。
當然,在生產環境中,我們的資料可能在不同的地方,例如關係型資料庫Postgre
,或者MQ
,再或者Redis
中,我們可以統一使用Logstash
進行資料的轉換,同時,也可以根據資料的熱度不同將ES
叢集架構為一種冷溫熱架構,利用ES
的多節點,將一天以內的資料稱謂熱資料,讀寫頻繁,就存放在ES
1.3.ES基本概念回顧
檔案(Document)
Elasticsearch
面向檔案性,檔案就是所有可搜尋資料的最小單位。比如,一篇PDF
中的內容,一部電影的內容,一首歌等,檔案會被序列化成JSON
格式,儲存在Elasticsearch
中,必不可少的是每個檔案都會有自己的唯一標識,可以自己指定,也可以由Elasticsearch
幫你生成。類似資料庫的一行資料。
元資料(標註檔案資訊)
"_index" : "user","_type" : "_doc","_id" : "l0D6UmwBn8Enzbv1XLz0","_score" : 1.6943597,"_source" : {
"user" : "mj","sex" : "男","age" : "18"
}
複製程式碼
-
_index
:檔案所屬的索引名稱。 -
_type
:檔案所屬的型別名。 -
_id
:檔案的唯一標識。 -
_version
:檔案的版本資訊。 -
_score
:檔案的相關性打分。 -
_source
:檔案的原始JSON
內容。
索引(index)
索引是檔案的容器,是一類檔案的集合,類似關係資料庫中的表,索引體現的是一種邏輯空間的概念,每個索引都應該有自己的Mapping
定義,用於定義包含檔案的欄位名和欄位型別。其中Shard
(分片)體現的是物理空間的一種概念,就是索引中的資料存放在Shard
上,因為有啦叢集,要保證高空用,當其中一個機器崩潰中,儲存在它上的分片資料也能被正常訪問,因此,存在啦分片副本。
索引中有兩個重要的概念,Mapping
和Setting
。Mapping
定義的是檔案欄位和欄位型別,Setting
定義的是資料的不同分佈。
型別(Type)
- 在7.0之前,一個
index
可以建立多個Type
。之後就只能一個index
對應一個Type
。
節點(Node)
一個節點就是一個Elaseticsearch
例項,本質就是一個JAVA
程式。每一個節點啟動後,預設就是一個master eligible
節點。就是具備成為master
資格的節點,你也可以狠心的指定它沒有這個資格(node.master:false
),
第一個節點啟動後,他就選自己成為Master
節點類,每一個節點上都儲存了叢集狀態,但是,只有Master
才能修改叢集狀態資訊。叢集狀態資訊就比如:
- 所有的節點資訊。
- 所有的索引資訊,索引對應的
mapping
資訊和setting
資訊。 - 分片的路由資訊。
分片(shard)
- 主分片:用於解決資料的水平擴充套件問題,通過主分片就資料分佈在叢集內的不同節點上,主分片在建立索引的時候就指定了,後面就不允許修改,除非重新定義
Index
。 - 副本:用於解決高可用的問題,分片是主分片的拷貝。副本分片數可以動態的調整,增加副本數量可以在一定的程度上提高服務的可用性。關於主分片的理解可以如下圖,看是怎樣實現高可用的,
"settings" : {
"index" : {
// 設定主分片數
"number_of_shards" : "1","auto_expand_replicas" : "0-1","provided_name" : "kibana_sample_data_logs","creation_date" : "1564753951554",// 設定副本分片數
"number_of_replicas" : "1","uuid" : "VVMLRyw6TZeSfUvvLNYXEw","version" : {
"created" : "7010099"
}
}
}
複製程式碼
1.4.倒排索引
正排索引:就是檔案ID
到檔案內容的索引,簡單講,就是根據ID
找檔案。
倒排索引:就是根據檔案內容找檔案。
倒排索引包含如下資訊:
- 單詞詞典:用於記錄所有檔案的單詞,以及單詞到倒排列表的關聯關係。
- 倒排列表:記錄的是單詞對應的檔案集合,由倒排索引項組成,其中包含
- 檔案ID
- 單詞出現的次數,用於相關性的評分
- 單詞出現的位置
- 偏移量,用於記錄單詞的開始位置和結束位置,用於單詞的高亮顯示
舉例說明什麼是正排索引和倒排索引,其中正排索引如下:
檔案ID | 檔案內容 |
---|---|
1101 | Elasticsearch Study |
1102 | Elasticsearch Server |
1103 | master Elasticsearch |
講上例Elasticsearch
單詞修改為倒排索引,如下:
檔案ID(Doc ID) | 出現次數(TF) | 位置(Position) | 偏移量(Offset) |
---|---|---|---|
1101 | 1 | 0 | <0,13> |
1102 | 1 | 0 | <0,13> |
1103 | 1 | 1 | <7,20> |
Elasticsearch
中的每一個欄位都有自己的倒排索引,也可以指定某些欄位不做索引,可以節省儲存空間,缺點就是不能被搜尋到。
1.5.Analyzer分詞
Analysis
:文字分析,就是將文字轉換為單詞(term
或者token
)的過程,其中Analyzer
就是通過Analysis
實現的,Elasticsearch
給我們內建例很多分詞器。
-
Standard Analyzer
:預設的分詞器,按照詞切分,並作大寫轉小寫處理 -
Simple Analyzer
:按照非字母切分(符號被過濾),並作大寫轉小寫處理 -
Stop Anayzer
:停用詞(the
、is
)切分,並作大寫轉小寫處理 -
Whitespace Anayzer
:空格切分,不做大寫轉小寫處理 -
IK
:中文分詞器,需要外掛安裝 -
ICU
:國際化的分詞器,需要外掛安裝 -
jieba
:時下流行的一箇中文分詞器。安裝方法見附錄
PS:
Elasticsearch
安裝外掛,[root@34d02ff9d16c elasticsearch]# bin/elasticsearch-plugin install analysis-icu
檢視已經安裝的外掛:
bin/elasticsearch-plugin list
1.6.Search API
在ES
中,我們可以使用URL Search
和Request Body Search
進行相關的查詢操作。
URL 查詢
使用基本的查詢
GET /user/_search?q=2012&df=title&sort=year:desc&from=0&size=10
{
?profile?: true
}
複製程式碼
- 使用
q
指定查詢的字串 - 使用
df
指定查詢的欄位 - 使用
sort
進行排序,使用from
和size
指定分頁 - 使用
profile
可以查詢查詢是如何進行查詢的
指定所有欄位的泛查詢
GET /user/_search?q=2012
{
"profile":"true"
}
複製程式碼
指定欄位的查詢
GET /user/_search?q=title:2012&sort=year:desc&from=0&size=10&timeout=1s
{
"profile":"true"
}
複製程式碼
Term查詢
GET /user/_search?q=title:Beautiful Mind
{
"profile":"true"
}
複製程式碼
- 上例中的
Beautiful
和Mind
就是兩個Term
,Term
是查詢中最小的單位。 -
Term
查詢是OR
的關係,在上例中就是title
欄位包含Beautiful
或者包含Mind
都會被檢索到。
Phrase查詢
GET /user/_search?q=title:"Beautiful Mind"
{
"profile":"true"
}
複製程式碼
- 使用引號表示
Phrase
查詢 -
Phrase
查詢表示的不僅是And
的關係,即Title
欄位中不僅要包含Beautiful Mind
,而且。順序還要一致。
分組查詢
GET /user/_search?q=title:(Beautiful Mind)
{
"profile":"true"
}
複製程式碼
- 使用中括號表示分組查詢,一般使用
Term
查詢的時候都會帶上分組查詢。
布林查詢
- 使用
AND
、OR
、NOT
或者||
、&&
、!
- 還可以使用
+
(表示must
),使用-
(表示must_not
) - 需要注意的是必須大寫
GET /user/_search?q=title:(Beautiful NOT Mind)
{
"profile":"true"
}
複製程式碼
GET /user/_search?q=title:(Beautiful %2BMind)
{
"profile":"true"
}
複製程式碼
PS:
%2B
表示的就是+
,上例子表示的就是title
欄位中既要包含Beautiful
,也要包含Mind
欄位
範圍查詢
GET /user/_search?q=title:beautiful AND age:[2002 TO 2018%7D
{
"profile":"true"
}
複製程式碼
- 使用
[ ]
表示閉區間,使用{ }
表示開區間,例如age :[* TO 56]
- 使用算術符表示範圍,例如
year :>=2019 && <=1970
PS:
URL Search
還有很多查詢方式。例如萬用字元查詢,正則插敘,模糊匹配,相似查詢,其中萬用字元查詢不建議使用。
Request Body 查詢
將查詢的條件引數放在Request Body
中,呼叫查詢介面,就是Request Body
查詢,
基本 的查詢
POST /movies,404_idx/_search?ignore_unavailable=true
{
"profile": true,"query": {
"match_all": {}
}
}
複製程式碼
- 使用
gnore_unavailable=true
可以避免索引404_idx
不存在導致的報錯 -
profile
和URL Search
查詢一樣,可以看到查詢的執行方式
分頁查詢
POST /movies/_search
{
"from":10,"size":20,"query":{
"match_all": {}
}
}
複製程式碼
排序查詢
POST /movies/_search
{
"sort":[{"order_date":"desc"}],"query":{
"match_all": {}
}
}
複製程式碼
過濾要查詢的欄位
POST /movies/_search
{
"_source":["order_date"],"query":{
"match_all": {}
}
}
複製程式碼
- 如果一個檔案中的欄位太多,我們不需全部欄位顯示,就可以使用
_source
指定欄位。可以使用萬用字元。
使用指令碼查詢
- 將
ES
中的檔案欄位進行一定的處理後,再根據這個新的欄位進行排序,
GET /movies/_search
{
"script_fields": {
"new_field": {
"script": {
"lang": "painless","source": "doc['name'].value+'是大佬'"
}
}
},"query": {
"match_all": {}
}
}
複製程式碼
Term查詢
POST /movies/_search
{
"query": {
"match": {
"title": "last christmas"
}
}
}
POST movies/_search
{
"query": {
"match": {
"title": {
"query": "last christmas","operator": "and"
}
}
}
}
複製程式碼
- 使用
match
,表示的就是OR
的關係 - 使用
operator
,表示查詢方式
Math_phrase查詢
POST movies/_search
{
"query": {
"match_phrase": {
"title":{
"query": "one love","slop": 4
}
}
}
}
複製程式碼
-
slop
指定查詢的字元中允許出現的字元
1.7.Dynamic Mapping
Mapping
可以簡單的理解為資料庫中的Schema
定義,用於定義索引中的欄位的名稱,定義欄位的型別,欄位的倒排索引,指定欄位使用何種分詞器等。Dynamic Mapping
意思就是在我們建立檔案的時候,如果索引不存在,就會自動的建立索引,同時自動的建立Mapping
,ElasticSearch
會自動的幫我們推算出欄位的型別,當然,也會存在推算不準確的時候,就需要我們手動的設定。常用的欄位型別如下:
- 簡單型別:
Text
、Date
、Integer
、Boolean
等 - 複雜型別:物件型別和巢狀型別。
我們可以使用GET /shgx/_mapping
查詢索引的Mapping
的設定,需要注意的是以下幾點:
- 當我們對索引中的檔案新增欄位時候,希望可以更新索引的
Mapping
就可以可以設定Dynamic:true
。 - 對於已經有資料的欄位,就不再允許修改其
Mapping
,因為Lucene
生成的倒排索引後就不允許修改。
Dynamic Mapping
可以設定三個值,分別是:
-
true
:檔案可被索引,新增欄位也可被索引,Mapping
也會被更新。 -
false
:檔案可被索引,新增欄位不能被索引,Mapping
不會被更新。 -
strict
:新增欄位寫入,直接報錯。
如何寫Mapping
第一種方式是參考官方API
,純手工寫,也可以先建立一個臨時的Index
讓ElasticSearch
自動當我們推斷出基本的Mapping
,然後自己在改吧改吧,最後把臨時索引刪掉就是啦。下面列舉一些常用的Mapping
設定屬性:
-
index
:可以設定改欄位是否需要被索引到。設定為false
就不會生成倒排索引,節省啦磁碟開銷 -
null_value
:可以控制NULL
是否可以被索引 -
cope_to
:將欄位值放在一個新的欄位中,可以使用新的欄位search
,但這個欄位不會出現在_source
中。 -
anaylzer
:指定欄位的分詞器 -
search_anaylzer
:指定索引使用的分詞器 -
index_options
:控制倒排索引的生成結構,有四種情況-
docs
:倒排索引只記錄檔案ID
-
freqs
:記錄檔案ID
和Term
-
positions
:記錄檔案ID
、Term
和Term Position
-
offsets
:記錄檔案ID
、Term
、Term Position
和offsets
-
PS:
Text
型別的欄位預設的是Position
,其它型別預設的是docs
,記錄的越多,佔用的儲存空間就越大。
1.8.Aggregation聚合分析
ElasticSearch
不僅僅是搜尋強大,他的統計功能也是相當的強大的,聚合分析就是統計整個資料的一個分類數量等,例如武侯區有多少新樓盤。天府新區有多少新樓盤,通過聚合分析我們只需要寫一條語句就可以得到。在加上Kibana
的視覺化分析,簡直就是清晰,高效。常用的集合有以下幾種:
-
Bucket Aggregation
:滿足特定條件的一些集合,使用關鍵字terms
-
Metric Aggregation
:簡單的數學運算,對欄位進行統計分析,使用關鍵字min
、max
、sum
、avg
等,使用關鍵字aggs
-
Pipeline Aggregation
:二次聚合 -
Matrix Aggregation
:對多個欄位進行操作,提供一個結果矩陣
Bucket分析示例
GET kibana_sample_data_flights/_search
{
"size": 0,"aggs":{
"flight_dest":{
"terms":{
"field":"DestCountry"
}
}
}
}
複製程式碼
Metric分析示例
GET kibana_sample_data_flights/_search
{
"size": 0,"aggs":{
"flight_dest":{
"terms":{
"field":"DestCountry"
},"aggs":{
"avg_price":{
"avg":{
"field":"AvgTicketPrice"
}
},"max_price":{
"max":{
"field":"AvgTicketPrice"
}
},"min_price":{
"min":{
"field":"AvgTicketPrice"
}
}
}
}
}
}
複製程式碼
附錄一
相關閱讀
- 安裝
docker
:www.docker.com/products/do… - 安裝
docker-compose
:docs.docker.com/compose/ins… -
Elasticsearch + Logstash + Kibana
的docker-compose
配置 :github.com/deviantony/… -
docker
安裝Elasticsearch
外掛 :www.elastic.co/cn/blog/ela… -
Elasticsearch
的中文社群elasticsearch.cn/ -
Beats
的產品:www.elastic.co/cn/download… - 不錯的中文分詞器:github.com/fxsjy/jieba
- 不錯的英文分詞器:github.com/nltk/nltk
-
IK
分詞器:github.com/medcl/elast… -
THULAC
分詞器,清華大學自然語言處理系的分詞器github.com/thunlp/THUL… -
ES
發展史:www.cnblogs.com/wangzhen379… - ELK6.0部署::Elasticsearch+Logstash+Kibana搭建分散式日誌平臺
- ElasticSearch叢集視覺化工具cerebro
- 測試資料集下載
更多文章,更好的閱讀體驗,請前往個人網站檢視 碼醬部落格