文章目錄
-
-
-
-
- 1、基礎
- 2、文法
- 3、基本查詢
- 4、進階查詢
-
-
-
1、基礎
- elasticsearch是一個分布式的全文搜尋引擎。
基于Lucene。具有restful的api接口。分布式,高橫向擴充能力。 全文檢索:分詞,在分詞庫想分詞後的關鍵詞。反向索引。
- 與solr的差別
效率: 單純的對已有資料進行檢索的時候,solr效率更好,高于es;在不斷動态添加資料的時候,solr的檢索效率會變的低下,而es則沒有什麼變化。 獨立性: Solr利用zookeeper進行分布式管理,而es自身帶有分布式系統管理功能。
- 反向索引也叫反向索引,通俗來講正向索引是通過key找value,反向索引則是通過value找key。
- type在7中已經被遺棄,ES官方建議 在一個索引庫中隻存儲相同類型的文檔。
-
ik分詞器
可以去GitHub下載下傳,但是網絡問題,可以進入容器,然後切到目錄 /usr/share/elasticsearch/bin。之後可以執行./elasticsearch-plugin install http://tomcat01.qfjava.cn:81/elasticsearch-analysis-ik-6.5.4.zip。最後重新開機一下。
POST _analyze { "analyzer": "ik_max_word", "text": "中國湖北" } # 分為了[中國]和[湖北]
2、文法
- field字段類型,常見如下
字元串類型 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
-
操作es的restful文法。原本的put修改,post新增,get查詢,delete删除
Get:查詢
Post:查詢# 查詢索引資訊 http://ip:port/index # 查詢文檔資訊 http://ip:port/index/type/doc_id
Put:建立索引# 查詢(查詢參數太多的情況,參數可以json格式傳參) http://ip:port/index/type/_search # 更新 http://ip:port/index/type/doc_id/_update #建立一個文檔(一條資料) http://ip:port/index/type/doc
Delete:删# 建立一個索引,請求體中指定資料結構(即type和字段,settings和mappings) http://ip:port/index # 建立一個文檔的屬性有哪些,請求體中指定具體資訊 http://ip:port/index/type/_mappings #建立一個文檔(一條資料) http://ip:port/index/type/doc
# 删除一個索引,對應的資料全部被删除了 http://ip:port/index # 删除一個文檔 http://ip:port/index/type/doc_id
-
具體操作
3.1 索引操作
建立一個索引
删除索引# 簡單建立一個索引,預設副本數為1,分片數為5 PUT /qsm # 簡單建立一個索引,指定副本數和分片數 PUT /qsm1 { "settings": { "number_of_shards": 5 , "number_of_replicas": 1 } } # 若已建立索引,給索引添加資料結構 PUT /qsm/novel/_mappings { "properties":{ "name":{ "type":"text" }, "author":{ "type":"keyword" }, "count":{ "type":"long" }, "onSale":{ "type":"date", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } # 建立一個索引并制定資料結構 PUT /book { "settings": { "number_of_shards": 5 , "number_of_replicas": 1 }, "mappings": { "novel":{ "properties":{ "name":{ "type":"text", "analyzer":"ik_max_word" }, "author":{ "type":"keyword" }, "count":{ "type":"long" }, "onSale":{ "type":"date", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } } }
檢視索引資訊# 删除某一個索引 DELETE /qsm # 删除某個字首的所有索引 DELETE /qsm*
# 檢視某個索引 GET /qsm1 # 檢視所有索引清單 GET /_cat/indices?v
3.2 文檔操作
建立文檔
更改文檔# 自動建立文檔id POST /book/novel { "name":"大秦帝國", "author":"qsm", "count":"10", "onSale":"2020-07-21" } # 手動建立文檔id POST /book/novel/1 { "name":"大清帝國", "author":"qsm", "count":"20", "onSale":"2020-07-11" }
删除文檔# 覆寫修改,直接相當于已知文檔id的手動建立 POST /book/novel/1 { "name":"大清帝國_copy", "author":"qsm", "onSale":"2020-07-11" } # 制定修改,基于doc POST /book/novel/1/_update { "doc": { "name":"大清帝國_copy2" } }
查詢文檔DELETE /book/novel/qk4vcHMBO6OsUd5sLTc
GET /book/novel/1
- 深分頁
ES對from和size之和有限制,不能大于1w
from+size原理:
根據使用者輸入的詞語進行分詞
将分詞後的分詞去分詞庫中進行檢索,得到文檔的id
去各個分片中拉去指定的資料
根據資料的score分數進行排序
根據from/limit進行篩選出指定的資料,其他資料舍棄
傳回結果
scroll+size原理:
根據使用者輸入的詞語進行分詞
将分詞後的分詞去分詞庫中進行檢索,得到文檔的id
将文檔的id【放入到一個es上下文中】
根據指定的size去各個分片中拉去指定的資料,并且拿完的文檔id會被上下文移除
若需要下一頁size的資料,則去es上下文中拿到文檔id
接下來跟第四步一樣,進行循環
是以scroll沒有分數,且不适合實時查詢。但是非常快,資源消耗少。
指定scroll查詢的時候,會給這個上下文指定過期時間(可以保持)。排序預設是id,也可以手動自定
# from+size POST /sms-logs-index/sms-logs-type/_search { "from": 0, "size": 2, "query": { "wildcard": { "smsContent": { "value": "*荊楚" } } } } # 指定scroll查詢 POST /sms-logs-index/sms-logs-type/_search?scroll=2m { "size": 2 , "query": { "match": { "smsContent": "荊楚" } }, "sort": [ { "fee": { "order": "desc" } } ] } #得到資料中"_scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA0yFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANMxZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADTQWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA02FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANNRZ3REZpa01EYlJONjVZYXUtbExJak5R" # scroll下一頁查詢 POST /_search/scroll { "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA0yFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANMxZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADTQWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA02FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANNRZ3REZpa01EYlJONjVZYXUtbExJak5R", "scroll":"2m" } # 删除scroll DELETE /_search/scroll/DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA4_FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAAOQRZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADkAWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA5CFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAAOQxZ3REZpa01EYlJONjVZYXUtbExJak5R
3、基本查詢
查詢的基本知識:
若想查詢短信資訊字段中包含“中國湖北”的資料。則ik分詞器會"中國湖北"分為“中國湖北”,“中國”,“湖北”,那麼有這三個字段的文檔都會比對查詢到,但是會有一個分數,分數最高則會最優質比對。
前提資料準備
建立索引
PUT /sms-logs-index
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 5
},
"mappings": {
"sms-logs-type":{
"properties":{
"corpName":{
"type":"keyword"
},
"smsContent":{
"type":"text",
"analyzer":"ik_max_word"
},
"fee":{
"type":"long"
},
"province":{
"type":"keyword"
},
"create":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
導入資料,可以自己随便編寫資料。編寫10條左右即可
POST /sms-logs-index/sms-logs-type
{
"corpName":"中國聯通",
"smsContent":"歡迎您來到齊魯大地,祝您平安愉快!撥打漫遊地區号+12580訂票訂房;辦理移動業務,請撥10086咨詢;中國聯通山東公司将竭誠為您服務。",
"fee":"30",
"province":"山東",
"create":"2020-05-19"
}
- match_all查詢
查詢所有,相當于沒有任何查詢條件。預設size為10
POST /sms-logs-index/sms-logs-type/_search { "query": { "match_all": {} } }
- match查詢
進階查詢,不同字段類型采用不同的查詢方式
日期或者數字,自動轉
keyword,不會分詞
text,會自動分詞
# match查詢 POST /sms-logs-index/sms-logs-type/_search { "query": { "match": { "smsContent": "中國電信" } } } # 注意:中國電信會被分詞為:中國移動、中國移、中國、移動。是以隻要文檔的smsContent字段内容包含了這四個詞的,都會被查出來,僅僅是分數會低一下,比如有的内容隻出現了[中國] # 現在更新為"smsContent": "齊魯",則展示結果如下 { "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 1.2005384, "hits" : [ { "_index" : "sms-logs-index", "_type" : "sms-logs-type", "_id" : "PLNYcHMB9IjDRQti4nhj", "_score" : 1.2005384, "_source" : { "corpName" : "中國聯通", "smsContent" : "歡迎您來到齊魯大地,祝您平安愉快!撥打漫遊地區号+12580訂票訂房;辦理移動業務,請撥10086咨詢;中國聯通山東公司将竭誠為您服務。", "fee" : "30", "province" : "山東", "create" : "2020-05-19" } } ] } } # 布爾match查詢 POST /sms-logs-index/sms-logs-type/_search { "query": { "match": { "smsContent": { "query": "齊魯 大地", "operator": "or" } } } }
- mutil_match查詢
之前是針對一個field的内容做value檢索,mutil_match則是針對多個filed中對該value做檢索
#mutil_match查詢 POST /sms-logs-index/sms-logs-type/_search { "query": { "multi_match": { "query": "中國熱線", "fields": ["corpName","smsContent"] } } } # 中國熱線,在corpName不會被分詞,在smsContent會被分詞
- term查詢
代表完全比對。不會分詞,直接去分詞庫中比對内容,是以很适合string文本類型為keyword類型的。
以“奮鬥的時代”為例:使用ik分詞器分為:奮鬥,奮,鬥,時代。但是term和terms是不分詞的,是以ik分詞器中是沒有“奮鬥的時代”這5個字的詞語,是以就查詢不到。即使後面正在的完整句子有改5個字的詞語。
POST /sms-logs-index/sms-logs-type/_search { "from": 0, "size": 20, "query": { "term": { "corpName": { "value": "中國移動" } } } }
- terms查詢
機制跟term一緻,不過它可以針對一個field字段的内容包含多個值的時候使用。如同sql中or。省份為北京或者上海或者遼甯
POST /sms-logs-index/sms-logs-type/_search { "from": 0, "size": 20, "query": { "terms": { "province": [ "遼甯", "山東" ] } } }
- id查詢
直接根據文檔的id擷取某一條資料
GET /sms-logs-index/sms-logs-type/PrNjcHMB9IjDRQtiY3hb
- ids查詢
根據多個id擷取
POST /sms-logs-index/sms-logs-type/_search { "query": { "ids": { "values": ["NrNWcHMB9IjDRQtiK3iX","PrNjcHMB9IjDRQtiY3hb"] } } }
- fuzzy模糊糾正查詢
根據查詢詞語,大概的去查詢資料。注意是大概,也就是很不穩定,因為查詢詞語可以是有錯别字等。比如,想去比對盒馬鮮生,輸入河馬先生也是有可能查詢的到。但是差距太大,則也有可能差不多。是以穩定性差
# 改為中國一動可以查詢的到,但是改為中國yi動則查詢不到 POST /sms-logs-index/sms-logs-type/_search { "query": { "fuzzy": { "corpName": { "value": "中國一動" } } } } # 前面3個字元一樣,這樣的話就查詢不到了 POST /sms-logs-index/sms-logs-type/_search { "query": { "fuzzy": { "corpName": { "value": "中國一動", "prefix_length": 3 } } } }
- prefix字首查詢
可以根據想搜尋字段的前面的一部分去搜尋。不僅僅适合text類型,也适用于keyword關鍵字類型的。都能查出
POST /sms-logs-index/sms-logs-type/_search { "query": { "prefix": { "smsContent": { "value": "尊敬" } } } }
- wildcard通配查詢
跟mysql的like查詢類似。通配符*為多個未知字元,?為一個字元。
非常消耗資源
POST /sms-logs-index/sms-logs-type/_search { "query": { "wildcard": { "corpName": { "value": "??電信" } } } } POST /sms-logs-index/sms-logs-type/_search { "query": { "wildcard": { "smsContent": { "value": "*荊楚" } } } }
- regexp正則查詢
正則比對的查詢
以上fuzzy、prefix、wildcard和regexp查詢效率低,耗費資源的。字首比對是優于wildcard和regexp。
POST /sms-logs-index/sms-logs-type/_search { "query": { "regexp": { "corpName": "中國聯通[0-9]{2}" } } } # 有一個資料 "corpName" : "中國聯通12"。是以該正則可以查到資料
- rang數字範圍查詢
範文查詢,針對數字
POST /sms-logs-index/sms-logs-type/_search { "query": { "range": { "fee": { "gte": 100, "lte": 200 } } } }
4、進階查詢
- delete_by_query
根據match或者term等基本查詢操作查詢到的資料進行删除
POST /sms-logs-index/sms-logs-type/_delete_by_query { "query":{ "range":{ "fee":{ "gte": 3000 } } } } # 結果如下deleted為2,删除了2條 { "took" : 32, "timed_out" : false, "total" : 2, "deleted" : 2, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ] }
- bool查詢
過濾器查詢,将多個查詢調教,以一定邏輯操作組合到一起
must:相當于都符合,and
must_not:相當于都不符合,not
should:相當于或者,or
filter:不計算分數,對經常過濾的資料進行緩存
# 省份為湖北或者北京 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "should": [ { "term": { "province": { "value": "湖北" } } }, { "term": { "province": { "value": "北京" } } } ] } } } #公司不是中國移動 #短信内容包含中國和大地 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "must_not": [ { "term": { "corpName": { "value": "中國移動" } } } ], "must": [ { "match": { "smsContent": "中國" } }, { "match": { "smsContent": "大地" } } ] } } } # 【注意】must和should混合使用的時候,發現should不起作用了。這個時候可以根據嚴謹的資料邏輯編寫查詢語句 # filter查詢 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "filter": [ { "term":{ "corpName": "中國移動" } }, { "range":{ "fee":{ "gte": 3000 } } } ] } } }
- filter查詢
query:查詢到的文檔的比對度會得到分數,并且排序,不會緩存,适合實時查詢
filter:查詢到的文檔不會計算分數,而是會對經常被過濾的資料進行緩存
# filter查詢 POST /sms-logs-index/sms-logs-type/_search { "query": { "bool": { "filter": [ { "term":{ "corpName": "中國移動" } }, { "range":{ "fee":{ "gte": 3000 } } } ] } } }
- boosting查詢
提升分數查詢。預設按照分數,但是有時候想改變一下排序權重
通過将文檔原本的_score和negative_boost參數進行相乘來得到新的_score。
positive查詢:比對到了positive查詢的文檔才會被包含到結果集中
negative查詢:滿足positive之後,又滿足negative,則比對的文檔會被降低其相關度
negative_boost系數小于1.0
# 正常查詢 POST /sms-logs-index/sms-logs-type/_search { "query": { "match": { "smsContent": "北京" } } } #boosting查詢 #短信内容有北京的,公司為中國移動的,則降低其分數 POST /sms-logs-index/sms-logs-type/_search { "query": { "boosting": { "positive": { "match": { "smsContent": "北京" } }, "negative": { "match": { "corpName": "中國移動" } }, "negative_boost": 0.2 } } }
- 高亮查詢
查詢的語句會被高亮顯示。
高亮的資料不會影響原來的資料,而是單獨将filed對應的資料以高亮傳回
POST /sms-logs-index/sms-logs-type/_search { "query": { "term": { "smsContent": "荊楚" } } , "highlight": { "fields": { "smsContent": { "pre_tags": "<font color='red'>", "post_tags": "</font>", "fragment_size": 10 } } } } #結果 { "_index" : "sms-logs-index", "_type" : "sms-logs-type", "_id" : "PbNicHMB9IjDRQti4Hgh", "_score" : 1.1748445, "_source" : { "corpName" : "中國電信", "smsContent" : "歡迎您來到荊楚大地大地,祝您平安愉快!撥打漫遊地區号+12580訂票訂房;辦理移動業務,請撥10086咨詢;中國電信荊州公司将竭誠為您服務。", "fee" : "30", "province" : "湖北", "create" : "2020-05-19" }, "highlight" : { "smsContent" : [ "歡迎您來到<font color='red'>荊楚</font>大地大地" ] } }
- 聚合查詢
使用aggs。在查詢資料的最後單獨展示
1、去重計數cardinality
2、範圍統計range。數值range,時間範圍date_range,ip範圍ip_date。from包含,to不包含。
3、統計查詢extended_stats,最大值,最小值,平均值等
- 經緯度查詢
根據地點在地圖的坐标,來确定一個範圍。看某個點在不在範圍中。字段filed的類型為geo_point。
确定範圍有,以直線确定一個圓;以2個點确定一個矩形;多個點連接配接為多邊形來确定一個範圍。
自此es基礎版筆記記錄完畢,若想檢視es進階功能和原理,請點選es進階版筆記(待續)
若想安裝es和kibana可以移步至docker安裝es和kibana——非常簡單
【暫完】
正在去BAT的路上修行