十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊
量身定制 + 運營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
這篇文章主要講解了“ElasticSearch查詢怎么使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“ElasticSearch查詢怎么使用”吧!
新野ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!
有兩種方法執(zhí)行搜索:第一種是通過REST request Uri 發(fā)送搜索參數(shù),第二種是通過REST request body。第二種方法允許你用json格式定義更豐富的查詢參數(shù)。我們將會用第一種方法做一個例子,但之后都會專一地使用第二種方法做實驗。
_search 返回 bank索引的所有文檔
GET /bank/_search?q=*&sort=account_number:asc
q=* :查詢所有
返回結(jié)果如下:
{ "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執(zhí)行搜索花費的毫秒數(shù)
timed_out-告訴我們這次搜索是否超時
_shards- 告訴我們搜索了多少個分片,以及搜索成功和失敗的分片數(shù)
hits-搜索返回的文檔結(jié)果
hits.total 一共命中了多少結(jié)果
sort-搜索排序規(guī)則,如果沒有該字段,則按相關(guān)度排序
_score和max_score 暫時先忽略這個參數(shù)(文檔得分,反映相關(guān)度)
下面用request body方法執(zhí)行和上面一樣的搜索操作:
GET /bank/_search { "query": { "match_all": {} }, "sort": [ { "account_number": "asc" } ] }
query
字段說明查詢內(nèi)容
match_all
是執(zhí)行查詢操作的匹配類型 , match_all
是匹配所有文檔的意思。
不同點是我們用json格式的請求體代替了_search api uri中的q=*參數(shù)。
必須要知道的是:當(dāng)我們接收到返回結(jié)果的時候,elasticsearch已經(jīng)完全處理了這個請求,不會維護(hù)任何的服務(wù)器資源或游標(biāo)到你的返回結(jié)果中。這與類似sql這樣的平臺形成鮮明的對比,sql允許你先取前面的一部分?jǐn)?shù)據(jù),然后連續(xù)不斷的通過服務(wù)器端的游標(biāo)再去取剩下的數(shù)據(jù)。
除了query
參數(shù),我們也可以傳遞其他參數(shù)去影響查詢結(jié)果。在上一章節(jié)的例子我們傳遞了一個sort參數(shù),這里我們傳遞一個size
GET /bank/_search { "query": { "match_all": {} }, "size": 1 }
注意,如果size沒有指定,默認(rèn)值是10.
下面這個例子匹配所有文檔,并返回第11-20的文檔:
GET /bank/_search { "query": { "match_all": {} }, "from": 10, "size": 10 }
from參數(shù)指定從第幾個文檔開始返回,size參數(shù)指定一共返回多少個文檔。這個特性是對分頁功能是十分重要的。如果from沒有指定,默認(rèn)值是0。
下面的例子按賬戶余額倒序查詢前10個結(jié)果(默認(rèn)size大?。?/p>
GET /bank/_search { "query": { "match_all": {} }, "sort": { "balance": { "order": "desc" } } }
現(xiàn)在我已經(jīng)看見過一些基礎(chǔ)的查詢參數(shù),讓我們挖掘更多關(guān)于query DSL 的信息。首先看看返回文檔的字段。默認(rèn)所有的字段都會被返回。文檔原始內(nèi)容被稱為源(對應(yīng)hits中的_source 鍵)。如果我們不想返回文檔的所有字段,也可以僅僅要求接口返回部分字段。
下面的例子展示如何返回 account_number 和balance(在_source里面)這個兩個字段:
GET /bank/_search { "query": { "match_all": {} }, "_source": ["account_number", "balance"] }
注意上述操作只是減少了返回的字段,但是_source
字段還是存在的,只是僅返回account_number
和balance
字段
如果你曾經(jīng)學(xué)過sql,上述概念就和sql select filed list from
差不多。
現(xiàn)在,讓我們繼續(xù)學(xué)習(xí)查詢語法。之前,我們已經(jīng)看到過match_all
查詢類型使用來匹配所有文檔的?,F(xiàn)在,我們介紹一種新的查詢類型match
,他是基于字段搜索的(即,通過匹配一個特定的字段或一組字段執(zhí)行搜索)
下面的例子返回賬號number是20的文檔:
GET /bank/_search { "query": { "match": { "account_number": 20 } } }
下面的例子返回所有地址字段包含mill
的賬戶文檔
GET /bank/_search { "query": { "match": { "address": "mill" } } }
下面的例子返回地址字段包含“mill”或者“l(fā)ane”的賬戶
GET /bank/_search { "query": { "match": { "address": "mill lane" } } }
下面的例子是match
的變種(match_phrase
),它返回所有地址字段包含詞組“mill lane”的賬戶
GET /bank/_search { "query": { "match_phrase": { "address": "mill lane" } } }
現(xiàn)在,讓我介紹一下布爾查詢。bool
查詢允許我們把多個match
查詢合并到一個查詢中。
下面的例子合并了兩個match
查詢并返回所有地址字段同時包含“mill”和“l(fā)ane”的賬戶
GET /bank/_search { "query": { "bool": { "must": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
上述例子的bool must
子句指定:當(dāng)所有的查詢都返回true的時候,才認(rèn)為匹配文檔。
與此相反,下面這個這個例子合并兩個match
查詢,并返回所有地址地段包含“mill”或“l(fā)ane”的賬戶
GET /bank/_search { "query": { "bool": { "should": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
上述例子,bool should
子句只要文檔滿足其中一個查詢,就認(rèn)為匹配。
下面的例子合并了兩個match
查詢,并返回所有地址字段既不包含“mill”也不包含“l(fā)ane”的賬戶:
GET /bank/_search { "query": { "bool": { "must_not": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
上面的例子中,bool must_not
子句指定當(dāng)所有查詢都不滿足的時候,就認(rèn)為匹配文檔。
我們也可以把must
,should
,must_not
同時組合到bool
子句。此外,我們也可以組合bool
到任何一個bool
子句中,實現(xiàn)復(fù)雜的多層bool
子句嵌套邏輯。
下面的例子返回所有年齡是40歲但不是住在ID州的賬戶:
GET /bank/_search { "query": { "bool": { "must": [ { "match": { "age": "40" } } ], "must_not": [ { "match": { "state": "ID" } } ] } } }
在之前的章節(jié),我們跳過了一個小細(xì)節(jié):文檔得分(搜索結(jié)果的_score
字段).文檔得分是一個數(shù)字值,它代表關(guān)鍵字和文檔內(nèi)容的相關(guān)度估值。 文檔得分越高說明相關(guān)度越高,文檔得分越少,說明相關(guān)度越少。
但查詢不一定都需要產(chǎn)生文檔得分,特別在過濾文檔集合的時候。為了避免不必要的文檔得分計算,Elasticsearch會檢查這種情況并自動的優(yōu)化這種查詢。
在前面章節(jié)介紹的bool
查詢也支持filter
子句,它允許你使用一個查詢語句去過濾其它子句的匹配結(jié)果,同時不會改變文檔的得分。我們介紹一下range
查詢,并把它作為例子,它允許我們通過一個范圍值去過濾文檔。通常用于數(shù)字或日期過濾。
這個例子使用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 } } } } } }
仔細(xì)分析上面的例子,bool
查詢包含了一個match_all
查詢(查詢部分)和一個range
查詢(過濾部分)。我們也可以用任何其它的查詢語句代替查詢和過濾部分的語句。對于上面的例子,因為所有文檔都是指定范圍之內(nèi)的,他們從某種意義上來說是等價的(equally),即他們的相關(guān)度都是一樣的(filter子句查詢,不會改變得分)。
除了 match_all
,match
,bool
,range
查詢,還有很多種類的查詢,但我們不在這里一一介紹。從現(xiàn)在開始,我們對查詢已經(jīng)有一個基礎(chǔ)的了解,把學(xué)到的知識應(yīng)用到其他查詢類型應(yīng)該也沒什么難度。
GET /bank/_search { "query": { "term": { "address": "789 Madison" } } }
GET /bank/_search { "query": { "match": { "address.keyword": "789 Madison" } } }
match
:模糊匹配,需要指定字段名,但是輸入會進(jìn)行分詞,比如"hello world"會進(jìn)行拆分為hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的結(jié)果都會被查詢出來,也就是說match是一個部分匹配的模糊查詢。查詢條件相對來說比較寬松。
term
: 這種查詢和match在有些時候是等價的,比如我們查詢單個的詞hello,那么會和match查詢結(jié)果一樣,但是如果查詢"hello world",結(jié)果就相差很大,因為這個輸入不會進(jìn)行分詞,就是說查詢的時候,是查詢字段分詞結(jié)果中是否有"hello world"的字樣,而不是查詢字段中包含"hello world"的字樣,elasticsearch會對字段內(nèi)容進(jìn)行分詞,"hello world"會被分成hello和world,不存在"hello world",因此這里的查詢結(jié)果會為空。這也是term查詢和match的區(qū)別。
match_phase
:會對輸入做分詞,但是需要結(jié)果中也包含所有的分詞,而且順序要求一樣。以"hello world"為例,要求結(jié)果中必須包含hello和world,而且還要求他們是連著的,順序也是固定的,hello that word不滿足,world hello也不滿足條件。
query_string
:和match類似,但是match需要指定字段名,query_string是在所有字段中搜索,范圍更廣泛。
不同于term,keyword精確匹配要求查詢的字段必須等于
一般我們?nèi)臋z索字段用match,其他非text字段匹配用term
聚合功能能夠分組并統(tǒng)計你的數(shù)據(jù)。最簡單的說法就是等價于sql group by
語句和sql的聚合函數(shù)。使用elasticsearch,你可以同時在一個請求中返回需要查詢的數(shù)據(jù)以及這些數(shù)據(jù)的多種聚合運算結(jié)果。在單個請求中就可以同時查詢數(shù)據(jù)和進(jìn)行多次聚合運算是非常有意義的,他可以降低網(wǎng)絡(luò)請求的次數(shù)。
下面的例子把state
字段的內(nèi)容分組,并按照每一組的文檔數(shù)量倒序排序,返回數(shù)量最多的前10(默認(rèn)值)組數(shù)據(jù):
GET /bank/_search { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" } } } }
上面的聚合運算等價于執(zhí)行下面的sql:
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
返回結(jié)果(僅展示一部分):
{ "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個賬戶。
注意我們設(shè)置size=0是因為我不需要查詢文檔,只需要查詢聚合結(jié)果。
基于上述例子,下面的例子除了分組還會計算每個州的賬戶的平均余額:
GET /bank/_search { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } }
注意我們是如何把average_balance聚合嵌入到group_by_state聚合中。這種模式適合于所有的聚合。你可以按你的需求重復(fù)嵌套聚合子句,匯總你的數(shù)據(jù)。
基于上面的例子,我們加入了按每個州的賬戶平均余額倒序排序的限制(說明了上一層聚合可以使用下一層聚合的運算結(jié)果):
GET /bank/_search { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword", "order": { "average_balance": "desc" } }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } }
下面例子講述了我們?nèi)绾伟茨挲g組分組(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查詢怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對ElasticSearch查詢怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!