es介绍和基本用法
ElasticSearch
轉載請注明出處。
引言
1.在海量數據中執行搜索功能時,如果使用MySQL, 效率太低。
2.如果關鍵字輸入的不準確,一樣可以搜索到想要的數據。
3.將搜索關鍵字,以紅色的字體展示。
介紹:
es是一個使用java語言并且基于Lucene編寫的搜索引擎框架,提供了分布式的全文搜索功能,提供了一個統一的基于restful風格的web接口。
- haystack:全文檢索的框架,支持whoosh、solr、Xapian、Elasticsearc四種全文檢索引擎,點擊查看官方網站。
- whoosh:純Python編寫的全文搜索引擎,雖然性能比不上sphinx、xapian、Elasticsearc等,但是無二進制包,程序不會莫名其妙的崩潰,對于小型的站點,whoosh已經足夠使用,點擊查看whoosh文檔。
- jieba:一款免費的中文分詞包,如果覺得不好用可以使用一些收費產品。
分布式:突出橫向擴展能力。
全文檢索:將一段詞語進行分詞,并且將分出的單個詞語統一的放到一個分詞庫中,在搜索時,根據關鍵字去分詞庫中檢索,找到匹配內容。(倒排索引)
端口:9200
倒排索引
1.將存放的數據,以一定的方式進行分詞,并且將分詞的數據存放到一個單獨的分詞庫中
2.當用戶去查詢數據時,會將用戶的查詢關鍵字進行分詞
3.然后去分詞庫中匹配內容,最終得到數據的id標識
4.根據id標識去存放數據的位置拉取到指定的數據
不會直接去存放數據的數據庫檢索而是先去分詞庫去檢索,再返回數據庫的數據
1.es服務中可以創建多個索引。
2.es服務每一個索引默認有5個分片。
3.每一個分片都會存在至少一個備份分片。
4.從分片默認是不會幫助檢索數據,當es檢索壓力特別大時,備份分片才會幫助檢索數據。
5.備份的分片必須放在不同的服務器中。
分片可以提高檢索效率,分片1會備份分片2中的數據,防止分片2掛掉
kibana
kibana端口:5601
查看索引的文檔信息
1.配置索引,點擊進行下一步
2.點擊Discover,進行查看
##啟動es和kibana
cd /Users/yutang/docker_es docker-compose up1.索引基本操作
1.1 創建一個索引
#創建一個person索引 PUT /person {"settings": {"number_of_shards": 5, //分片數"number_of_replicas": 1 //備份數} }1.2 查看索引信息
#查看索引 GET /person1.3 刪除索引
#刪除索引 DELETE /person1.4 ES中Field可以指定的類型
官網地址核心數據類型地址:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/mapping-types.html
字符串String:text:一般用于全文檢索。將當前的field進行分詞keyword: 當前的Field不可被分詞 數值類型Numeric:long, integer, short, byte, double, float, half_float,scaled_float 時間類型Data:date,可以指定具體的格式 布爾類型Boolean:boolean 二進制類型Binary:binary 范圍類型Range:integer_range, float_range, long_range, double_range, date_range 經緯度類型:geo_point:用來存儲經緯度 ip類型:ip:可以存儲ipv4或者ipv61.5 創建索引并指定數據結構
以創建小說為例子
PUT /book {"settings": {//備份數"number_of_replicas": 1,//分片數"number_of_shards": 5},//指定具體的數據結構"mappings": {//指定類型 Type"novel": {//文件存儲的Field屬性名"properties": {"name": {"type": "text",//指定分詞器的名稱"analyzer": "ik_max_word",//指定當前的Field可以作為查詢的條件,默認是true"index": true},"authoor": {"type": "keyword"},// 字數"count": {"type": "long"},"onSale": {"type": "date","format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"},"descr": {"type": "text"}}}} }1.6 文檔的操作
文檔在ES服務中的唯一標志,_index, _type, _id 三個內容為組合,來鎖定一個文檔,操作抑或是修改
PUT要指定id,不然會失敗;POST則不用
1.6.1 新建文檔
- 自動生成id
- 手動指定ID(更推薦)
1.6.2 修改文檔
-
覆蓋式修改
# 直接覆蓋id為1的數據 PUT /book/novel/1 {"name": "三國演義","authoor": "小明","onsale": "2020-12-11" } -
doc修改方式(更推薦)
POST /book/novel/1/_update {"doc": {"name": "極品家丁"} } #先鎖定文檔,_update 修改需要的字段即可
1.6.3 刪除文檔
-
刪庫
DELETE /book/novel/1
1.6.4 查詢結果過濾
_source 過濾顯示指定字段
POST /book/novel/_search {"query": {"match_all": {}},"_source": ["name", "authoor"] }1.6.5 排序
sort 按照指定順序返回,此時的_score是nul
POST /book/novel/_search {"query": {"match_all": {}},"sort": [{"count": {"order": "desc" //降序}}] }2.ElasticSearch練習
-
索引 : sms-logs-index
-
類型:sms-logs-type
| createDate | 創建時間String |
| sendDate | 發送時間 date |
| longCode | 發送長號碼 如 16092389287811 string |
| Mobile | 如 13000000000 |
| corpName | 發送公司名稱,需要分詞檢索 |
| smsContent | 下發短信內容,需要分詞檢索 |
| State | 短信下發狀態 0 成功 1 失敗 integer |
| Operatorid | 運營商編號1移動2聯通3電信 integer |
| Province | 省份 |
| ipAddr | 下發服務器IP地址 |
| replyTotal | 短信狀態報告返回時長 integer |
| Fee | 扣費 integer |
-
數據導入部分
PUT /sms_logs_index/sms_logs_type/1 {"corpName": "途虎養車","createDate": "2020-1-22","fee": 3,"ipAddr": "10.123.98.0","longCode": 106900000009,"mobile": "1738989222222","operatorid": 1,"province": "河北","relyTotal": 10,"sendDate": "2020-2-22","smsContent": "【途虎養車】親愛的燈先生,您的愛車已經購買","state": 0 }
3. ES的各種查詢
4.1 term&terms查詢
4.1.1 term查詢
term的查詢是代表完全匹配,搜索之前不會對你搜索的關鍵字進行分詞,對你的關鍵字去文檔分詞庫中去匹配內容。
#term匹配查詢 查詢身份是北京的數據 POST /sms_logs_index/sms_logs_type/_search {// limit from,size返回5條數據"from": 0, "size": 5,"query": {"term": { // term查詢"province": {"value": "河北"}}} } ##完成的匹配,不會對term中所匹配的值進行分詞查詢4.1.2terms查詢
terms是針對一個字段包含多個值得運用
類似where province = 河北 or province = xxx or province = xxxx
#terms 匹配查詢省份是河北或者河南的數據 POST /sms_logs_index/sms_logs_type/_search {"from": 0,"size": 5,"query": {"terms": {"province": ["河北","河南","武漢"]}} }4.2 match查詢
match查詢屬于高層查詢,它會根據你查詢字段類型不一樣,采用不同的查詢方式
match查詢,實際底層就是多個term查詢,將多個term查詢的結果進行了封裝
-
查詢的如果是日期或者是數值的話,它會基于你的字符串查詢內容轉換為日期或者是數值對待
-
如果查詢的內容是一個不可被分的內容(keyword),match查詢不會對你的查詢的關鍵字進行分詞
-
如果查詢的內容是一個可被分的內容(text),match則會將你指定的查詢內容按照一定的方式去分詞,去分詞庫中匹配指定的內容
4.2.1 match_all查詢
查詢全部內容,不指定任何查詢條件,但只展示10條
POST /sms_logs_index/sms_logs_type/_search {"query": {"match_all": {}} }4.2.2 match查詢 根據某個Field
指定一個Field作為篩選條件
POST /sms_logs_index/sms_logs_type/_search {"query": {"match": {// 收貨安裝 會進行分詞查詢"smsContent": "收貨安裝"}} }4.2.3 布爾match查詢
基于一個Filed匹配的內容,采用and或者or的方式進行連接
# 布爾match查詢 POST /sms_logs_index/sms_logs_type/_search {"query": {"match": {"smsContext": {// 查詢smsContext既包含 中國 又包括 健康"query": "中國 健康","operator": "and" #or}}} }4.2.4 multi_match查詢
match針對一個field做檢索,multi_match針對多個field進行檢索,多個key對應一個text
# 查詢 "province","smsContext" 包含 北京 的數據 POST /sms_logs_index/sms_logs_type/_search {"query": {"multi_match": {"query": "河北", // 指定text"fields": ["province","smsContext"] //指定field}} }4.3 ES 的其他查詢
4.3.1 ID 查詢
# id查詢 GET /sms_logs_index/sms_logs_type/1 GET /索引名/type類型/id4.3.2 ids查詢
根據多個id進行查詢,類似MySql中的where Id in (id1,id2,id3….)
POST /sms_logs_index/sms_logs_type/_search {"query": {"ids": {"values": [1,2,3] #id值}} }4.3.3 prefix查詢
前綴查詢,可以通過一個關鍵字去指定一個Field的前綴,從而查詢到指定的文檔
POST /sms_logs_index/sms_logs_type/_search {"query": {"prefix": {"corpName": {"value": "河"}}} } #與 match查詢的不同在于,prefix類似mysql中的模糊查詢。而match的查詢類似于嚴格匹配查詢 # 針對不可分割詞keyword4.3.4 fuzzy查詢
fuzzy查詢:模糊查詢,我們可以輸入一個字符的大概,ES就可以根據輸入的內容大概去匹配一下結果,eg.你可以存在一些錯別字
#fuzzy查詢 #fuzzy查詢 POST /sms_logs_index/sms_logs_type/_search {"query": {"fuzzy": {"corpName": {"value": "盒馬生鮮","prefix_length": 2 # 指定前幾個字符要嚴格匹配}}} }#不穩定,查詢字段差太多也可能查不到4.3.5 wildcard查詢
通配查詢,與mysql中的like查詢是一樣的,可以在查詢時,在字符串中指定通配符*和占位符?
#wildcard查詢 POST /sms_logs_index/sms_logs_type/_search {"query": {"wildcard": {"corpName": {"value": "*車" # 可以使用*和?指定通配符和占位符}}} } # ?代表一個占位符 # ??代表兩個占位符4.3.6 range查詢
范圍查詢,只針對數值類型,對某一個Field進行大于或者小于的范圍指定
POST /sms_logs_index/sms_logs_type/_search {"query": {"range": {"fee": {"gte": 0, "lte": 3}}} }#查詢范圍:[gte,lte] #查詢范圍:(gt,lt)4.3.7 regexp查詢
正則查詢,通過你編寫的正則表達式去匹配內容
PS: **prefix,fuzzy,wildcar和regexp查詢效率相對比較低,**在對效率要求比較高時,避免去使用
POST /sms_logs_index/sms_logs_type/_search {"query": {"regexp": {"mobile": "180[0-9]{8}" //匹配的正則規則}} }4.4 深分頁Scroll
ES對from+size這種分頁形式是有限制,from和size兩者之和不能超過1w,超過之后效率非常慢
原理:
from+size ES查詢數據的方式:1 先將用戶指定的關鍵詞進行分詞處理2 將詞匯去分詞庫中進行檢索,得到多個文檔的id3 去各個分片中拉去指定的數據 耗時4 根據數據的得分進行排序 耗時5 根據from的值,將查詢到的數據舍棄一部分6 返回查詢結果Scroll+size 在ES中查詢方式:1 先將用戶指定的關鍵詞進行分詞處理2 將詞匯去分詞庫中進行檢索,得到多個文檔的id3 將文檔的id存放在一個ES的上下文中,ES內存4 根據你指定給的size的個數去ES中檢索指定個數的數據,拿完數據的文檔id,會從上下文中移除5 如果需要下一頁的數據,直接去ES的上下文中(內存中),找后續內容6 循環進行4.5操作-
不會直接拉取數據,是存儲對應數據的id,需要數據時在根據id去拿;而from則是直接獲取數據
-
缺點,Scroll是從內存中去拿去數據的,不適合做實時的查詢,拿到的數據不是最新的
4.5 delete-by-query
根據term,match等查詢方式去刪除大量的文檔
如果你需要刪除的內容,是index下的大部分數據,不建議使用,建議逆向操作,創建新的索引,添加需要保留的數據內容
POST /sms_logs_index/sms_logs_type/_delete_by_query {// 正常的查詢語句"query": {"range": {"relyTotal": {"gte": 2,"lte": 3}}} }## 中間跟你的查詢條件,查到什么,刪什么4.6 復合查詢
4.6.1 bool查詢
復合過濾器,可以將多個查詢條件以一定的邏輯組合在一起,and or
-
must:所有的條件,用must組合在一起,表示AND
-
must_not:將must_not中的條件,全部不能匹配,表示not的意思,不能匹配該查詢條件
-
should:所有條件,用should組合在一起,表示or的意思,文檔必須匹配一個或者多個查詢條件
-
filter:過濾器,文檔必須匹配該過濾條件,跟must子句的唯一區別是,filter不影響查詢的score
4.6.2 boosting 查詢
boosting 查詢可以幫助我們去影響查詢后的score
-
positive:只有匹配上positive 查詢的內容,才會被放到返回的結果集中
-
negative:如果匹配上了positive 也匹配上了negative, 就可以降低這樣的文檔score
-
negative_boost:指定score系數,必須小于1,減小分數 0.5
關于查詢時,分數時如何計算的:
-
搜索的關鍵字再文檔中出現的頻次越高,分數越高
-
指定的文檔內容越短,分數越高。
-
我們再搜索時,指定的關鍵字也會被分詞,這個被分詞的內容,被分詞庫匹配的個數越多,分數就越高。
4.7 filter 查詢
query 查詢:根據你的查詢條件,去計算文檔的匹配度得到一個分數,并根據分數排序,不會做緩存的。用于獲取匹配度最高大的數據
filter 查詢:根據查詢條件去查詢文檔,不去計算分數,也就不用排序,而且filter會對經常被過濾的數據進行緩存。不需要關注匹配的數據,追求效率
#filter 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"bool": {"filter": [{"term": {"corpName": "海爾智家公司"}},{"range":{"fee":{"lte":50}}}]}} }4.8 高亮查詢
高亮查詢就是用戶輸入的關鍵字,以一定特殊樣式展示給用戶,讓用戶知道為什么這個結果被檢索出來
高亮展示的數據,本身就是文檔中的一個field,單獨將field以highlight的形式返回給用戶
ES提供了一個highlight 屬性,他和query 同級別。
-
frament_size:指定高亮數據展示多少個字符回來
-
pre_tags:指定前綴標簽
-
post_tags:指定后綴標簽
-
fields:指定哪個字段以高亮顯示,可以指定多個
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hzvmLtSs-1604200945451)(/Users/yutang/Library/Application Support/typora-user-images/image-20201004125436720.png)]
4.9 聚合查詢
ES的聚合查詢和mysql 的聚合查詢類似,ES的聚合查詢相比mysql 要強大得多。ES提供的統計數據的方式多種多樣。
#ES 聚合查詢的RSTFul 語法 POST /index/type/_search {"aggs":{"(名字)agg":{ // 自己取名字"agg_type":{"屬性":"值"}}} }4.9.1 去重計數聚合查詢
去重計數,cardinality 先將返回的文檔中的一個指定的field進行去重,統計一共有多少條
# 去重計數 查詢 province POST /sms-logs-index/sms-logs-type/_search {"aggs": {"provinceAgg": {"cardinality": {"field": "province"}}} }[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-oOhlE6qR-1604200945452)(/Users/yutang/Library/Application Support/typora-user-images/image-20201004134750613.png)]
4.9.2 范圍統計
統計一定范圍內出現的文檔個數,比如,針對某一個field 的值再0100,100200,200~300 之間文檔出現的個數分別是多少
范圍統計可以針對普通的數值,針對時間類型,針對ip類型都可以響應。
-
數值 range
-
時間 date_range
-
ip ip_range
4.9.3 統計聚合
他可以幫你查詢指定field 的最大值,最小值,平均值,平方和…
使用 extended_stats
# 統計聚合查詢 extended_stats POST /sms-logs-index/sms-logs-type/_search {"aggs": {"agg": {"extended_stats": {"field": "count"}}} } # 結果 "aggregations" : {"NAME" : {"count" : 1,"min" : 100000.0,"max" : 100000.0,"avg" : 100000.0,"sum" : 100000.0,"sum_of_squares" : 1.0E10,"variance" : 0.0,"std_deviation" : 0.0,"std_deviation_bounds" : {"upper" : 100000.0,"lower" : 100000.0}}}4.9.4 其他聚合查詢 查看官方文檔
https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-aggregations-metrics-weight-avg-aggregation.html
4.10 地圖經緯度搜索
#創建一個經緯度索引,指定一個 name ,一個location PUT /map {"settings": {"number_of_shards": 5,"number_of_replicas": 1},"mappings": {"map":{"properties":{"name":{"type":"text"},"location":{"type":"geo_point" //經緯度類型}}}} }#添加測試數據 PUT /map/map/1 {"name":"天安門","location":{"lon": 116.403694,"lat":39.914492} }PUT /map/map/2 {"name":"百望山","location":{"lon": 116.26284,"lat":40.036576} }PUT /map/map/3 {"name":"北京動物園","location":{"lon": 116.347352,"lat":39.947468} }4.10.1 ES 的地圖檢索方式
geo_distance:直線距離檢索方式
geo_bounding_box:以2個點確定一個矩形,獲取再矩形內的數據
geo_polygon:以多個點,確定一個多邊形,獲取多邊形的全部數據
####4.10.2 基于RESTFul 實現地圖檢索
#geo_distance POST /map/map/_search {"query": {"geo_distance":{// 確定一個點"location":{"lon":116.434739,"lat":39.909843},// 確定半徑 單位是米"distance":20000,// 指定形狀為圓形"distance_type":"arc"}} } #geo_bounding_box POST /map/map/_search {"query":{"geo_bounding_box":{"location":{"top_left":{"lon":116.327805,"lat":39.95499},"bottom_right":{"lon": 116.363162,"lat":39.938395}}}} } #geo_polygon POST /map/map/_search {"query":{"geo_polygon":{"location":{// 指定多個點確定 位置"points":[{"lon":116.220296,"lat":40.075013},{"lon":116.346777,"lat":40.044751},{"lon":116.236106,"lat":39.981533} ]}}} }總結
- 上一篇: 随笔是什么意思?
- 下一篇: IEEE754 16进制浮点型 转为十进