您好,登錄后才能下訂單哦!
這篇文章主要講解了“ElasticSearch查詢怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“ElasticSearch查詢怎么使用”吧!
有兩種方法執行搜索:第一種是通過REST request Uri 發送搜索參數,第二種是通過REST request body。第二種方法允許你用json格式定義更豐富的查詢參數。我們將會用第一種方法做一個例子,但之后都會專一地使用第二種方法做實驗。
_search 返回 bank索引的所有文檔
GET /bank/_search?q=*&sort=account_number:asc
q=* :查詢所有
返回結果如下:
{ "took" : 82, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1000, "max_score" : null, "hits" : [ { "_index" : "bank", "_type" : "account", "_id" : "0", "sort": [0], "_score" : null, "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"} }, { "_index" : "bank", "_type" : "account", "_id" : "1", "sort": [1], "_score" : null, "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"} }, ... ] } }
took-elasticsearch執行搜索花費的毫秒數
timed_out-告訴我們這次搜索是否超時
_shards- 告訴我們搜索了多少個分片,以及搜索成功和失敗的分片數
hits-搜索返回的文檔結果
hits.total 一共命中了多少結果
sort-搜索排序規則,如果沒有該字段,則按相關度排序
_score和max_score 暫時先忽略這個參數(文檔得分,反映相關度)
下面用request body方法執行和上面一樣的搜索操作:
GET /bank/_search { "query": { "match_all": {} }, "sort": [ { "account_number": "asc" } ] }
query
字段說明查詢內容
match_all
是執行查詢操作的匹配類型 , match_all
是匹配所有文檔的意思。
不同點是我們用json格式的請求體代替了_search api uri中的q=*參數。
必須要知道的是:當我們接收到返回結果的時候,elasticsearch已經完全處理了這個請求,不會維護任何的服務器資源或游標到你的返回結果中。這與類似sql這樣的平臺形成鮮明的對比,sql允許你先取前面的一部分數據,然后連續不斷的通過服務器端的游標再去取剩下的數據。
除了query
參數,我們也可以傳遞其他參數去影響查詢結果。在上一章節的例子我們傳遞了一個sort參數,這里我們傳遞一個size
GET /bank/_search { "query": { "match_all": {} }, "size": 1 }
注意,如果size沒有指定,默認值是10.
下面這個例子匹配所有文檔,并返回第11-20的文檔:
GET /bank/_search { "query": { "match_all": {} }, "from": 10, "size": 10 }
from參數指定從第幾個文檔開始返回,size參數指定一共返回多少個文檔。這個特性是對分頁功能是十分重要的。如果from沒有指定,默認值是0。
下面的例子按賬戶余額倒序查詢前10個結果(默認size大小):
GET /bank/_search { "query": { "match_all": {} }, "sort": { "balance": { "order": "desc" } } }
現在我已經看見過一些基礎的查詢參數,讓我們挖掘更多關于query DSL 的信息。首先看看返回文檔的字段。默認所有的字段都會被返回。文檔原始內容被稱為源(對應hits中的_source 鍵)。如果我們不想返回文檔的所有字段,也可以僅僅要求接口返回部分字段。
下面的例子展示如何返回 account_number 和balance(在_source里面)這個兩個字段:
GET /bank/_search { "query": { "match_all": {} }, "_source": ["account_number", "balance"] }
注意上述操作只是減少了返回的字段,但是_source
字段還是存在的,只是僅返回account_number
和balance
字段
如果你曾經學過sql,上述概念就和sql select filed list from
差不多。
現在,讓我們繼續學習查詢語法。之前,我們已經看到過match_all
查詢類型使用來匹配所有文檔的。現在,我們介紹一種新的查詢類型match
,他是基于字段搜索的(即,通過匹配一個特定的字段或一組字段執行搜索)
下面的例子返回賬號number是20的文檔:
GET /bank/_search { "query": { "match": { "account_number": 20 } } }
下面的例子返回所有地址字段包含mill
的賬戶文檔
GET /bank/_search { "query": { "match": { "address": "mill" } } }
下面的例子返回地址字段包含“mill”或者“lane”的賬戶
GET /bank/_search { "query": { "match": { "address": "mill lane" } } }
下面的例子是match
的變種(match_phrase
),它返回所有地址字段包含詞組“mill lane”的賬戶
GET /bank/_search { "query": { "match_phrase": { "address": "mill lane" } } }
現在,讓我介紹一下布爾查詢。bool
查詢允許我們把多個match
查詢合并到一個查詢中。
下面的例子合并了兩個match
查詢并返回所有地址字段同時包含“mill”和“lane”的賬戶
GET /bank/_search { "query": { "bool": { "must": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
上述例子的bool must
子句指定:當所有的查詢都返回true的時候,才認為匹配文檔。
與此相反,下面這個這個例子合并兩個match
查詢,并返回所有地址地段包含“mill”或“lane”的賬戶
GET /bank/_search { "query": { "bool": { "should": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
上述例子,bool should
子句只要文檔滿足其中一個查詢,就認為匹配。
下面的例子合并了兩個match
查詢,并返回所有地址字段既不包含“mill”也不包含“lane”的賬戶:
GET /bank/_search { "query": { "bool": { "must_not": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
上面的例子中,bool must_not
子句指定當所有查詢都不滿足的時候,就認為匹配文檔。
我們也可以把must
,should
,must_not
同時組合到bool
子句。此外,我們也可以組合bool
到任何一個bool
子句中,實現復雜的多層bool
子句嵌套邏輯。
下面的例子返回所有年齡是40歲但不是住在ID州的賬戶:
GET /bank/_search { "query": { "bool": { "must": [ { "match": { "age": "40" } } ], "must_not": [ { "match": { "state": "ID" } } ] } } }
在之前的章節,我們跳過了一個小細節:文檔得分(搜索結果的_score
字段).文檔得分是一個數字值,它代表關鍵字和文檔內容的相關度估值。 文檔得分越高說明相關度越高,文檔得分越少,說明相關度越少。
但查詢不一定都需要產生文檔得分,特別在過濾文檔集合的時候。為了避免不必要的文檔得分計算,Elasticsearch會檢查這種情況并自動的優化這種查詢。
在前面章節介紹的bool
查詢也支持filter
子句,它允許你使用一個查詢語句去過濾其它子句的匹配結果,同時不會改變文檔的得分。我們介紹一下range
查詢,并把它作為例子,它允許我們通過一個范圍值去過濾文檔。通常用于數字或日期過濾。
這個例子使用bool
查詢返回所有賬戶余額在20000-30000之間的文檔。換句話說,我們需要查找余額大于20000小于30000的賬戶:
GET /bank/_search { "query": { "bool": { "must": { "match_all": {} }, "filter": { "range": { "balance": { "gte": 20000, "lte": 30000 } } } } } } { "query": { "bool": { "must": { "match_all": {} }, "filter": { "range": { "balance": { "gte": 20000, "lte": 30000 } } } } } }
仔細分析上面的例子,bool
查詢包含了一個match_all
查詢(查詢部分)和一個range
查詢(過濾部分)。我們也可以用任何其它的查詢語句代替查詢和過濾部分的語句。對于上面的例子,因為所有文檔都是指定范圍之內的,他們從某種意義上來說是等價的(equally),即他們的相關度都是一樣的(filter子句查詢,不會改變得分)。
除了 match_all
,match
,bool
,range
查詢,還有很多種類的查詢,但我們不在這里一一介紹。從現在開始,我們對查詢已經有一個基礎的了解,把學到的知識應用到其他查詢類型應該也沒什么難度。
GET /bank/_search { "query": { "term": { "address": "789 Madison" } } }
GET /bank/_search { "query": { "match": { "address.keyword": "789 Madison" } } }
match
:模糊匹配,需要指定字段名,但是輸入會進行分詞,比如"hello world"會進行拆分為hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的結果都會被查詢出來,也就是說match是一個部分匹配的模糊查詢。查詢條件相對來說比較寬松。
term
: 這種查詢和match在有些時候是等價的,比如我們查詢單個的詞hello,那么會和match查詢結果一樣,但是如果查詢"hello world",結果就相差很大,因為這個輸入不會進行分詞,就是說查詢的時候,是查詢字段分詞結果中是否有"hello world"的字樣,而不是查詢字段中包含"hello world"的字樣,elasticsearch會對字段內容進行分詞,"hello world"會被分成hello和world,不存在"hello world",因此這里的查詢結果會為空。這也是term查詢和match的區別。
match_phase
:會對輸入做分詞,但是需要結果中也包含所有的分詞,而且順序要求一樣。以"hello world"為例,要求結果中必須包含hello和world,而且還要求他們是連著的,順序也是固定的,hello that word不滿足,world hello也不滿足條件。
query_string
:和match類似,但是match需要指定字段名,query_string是在所有字段中搜索,范圍更廣泛。
不同于term,keyword精確匹配要求查詢的字段必須等于
一般我們全文檢索字段用match,其他非text字段匹配用term
聚合功能能夠分組并統計你的數據。最簡單的說法就是等價于sql group by
語句和sql的聚合函數。使用elasticsearch,你可以同時在一個請求中返回需要查詢的數據以及這些數據的多種聚合運算結果。在單個請求中就可以同時查詢數據和進行多次聚合運算是非常有意義的,他可以降低網絡請求的次數。
下面的例子把state
字段的內容分組,并按照每一組的文檔數量倒序排序,返回數量最多的前10(默認值)組數據:
GET /bank/_search { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" } } } }
上面的聚合運算等價于執行下面的sql:
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
返回結果(僅展示一部分):
{ "took": 29, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits" : { "total" : 1000, "max_score" : 0.0, "hits" : [ ] }, "aggregations" : { "group_by_state" : { "doc_count_error_upper_bound": 20, "sum_other_doc_count": 770, "buckets" : [ { "key" : "ID", "doc_count" : 27 }, { "key" : "TX", "doc_count" : 27 }, { "key" : "AL", "doc_count" : 25 }, { "key" : "MD", "doc_count" : 25 }, { "key" : "TN", "doc_count" : 23 }, { "key" : "MA", "doc_count" : 21 }, { "key" : "NC", "doc_count" : 21 }, { "key" : "ND", "doc_count" : 21 }, { "key" : "ME", "doc_count" : 20 }, { "key" : "MO", "doc_count" : 20 } ] } } }
我們可以看到,ID州有27個賬戶,隨后的TX州有27個賬戶,AL州有25個賬戶。
注意我們設置size=0是因為我不需要查詢文檔,只需要查詢聚合結果。
基于上述例子,下面的例子除了分組還會計算每個州的賬戶的平均余額:
GET /bank/_search { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } }
注意我們是如何把average_balance聚合嵌入到group_by_state聚合中。這種模式適合于所有的聚合。你可以按你的需求重復嵌套聚合子句,匯總你的數據。
基于上面的例子,我們加入了按每個州的賬戶平均余額倒序排序的限制(說明了上一層聚合可以使用下一層聚合的運算結果):
GET /bank/_search { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword", "order": { "average_balance": "desc" } }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } }
下面例子講述了我們如何按年齡組分組(20-29,30-39,40-49),然后按性別分組,最后獲取每個組中每個性別的賬戶平均余額。(例如:年齡段在20-29的女性用戶的賬戶平均余額)
GET /bank/_search { "size": 0, "aggs": { "group_by_age": { "range": { "field": "age", "ranges": [ { "from": 20, "to": 30 }, { "from": 30, "to": 40 }, { "from": 40, "to": 50 } ] }, "aggs": { "group_by_gender": { "terms": { "field": "gender.keyword" }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } } } }
最后一個例子,查出所有年齡分布,并且這些年齡段中性別M的平均薪資和F的平均薪資以及這個年齡段的總體平均薪資
GET /bank/_search { "size": 0, "aggs":{ "aggAgg": { "terms": { "field": "age" }, "aggs": { "ageBalanceAvg":{ "avg": { "field": "balance" } }, "genderAgg":{ "terms":{ "field": "gender.keyword" }, "aggs": { "avgAvg":{ "avg": { "field": "balance" } } } } } } } }
感謝各位的閱讀,以上就是“ElasticSearch查詢怎么使用”的內容了,經過本文的學習后,相信大家對ElasticSearch查詢怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。