前言
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
- 測試資料集下載
更多文章,更好的閱讀體驗,請前往個人網站檢視 碼醬部落格