1.排序
elasticsearch默認(rèn)是根據(jù)相關(guān)度算分(_score)來排序,但是也支持自定義方式對搜索結(jié)果排序。可以排序字段類型有:keyword類型、數(shù)值類型、地理坐標(biāo)類型、日期類型等。
1.1.普通字段排序
keyword、數(shù)值、日期類型排序的語法基本一致。
語法:
GET?/indexName/_search
{
??"query":?{
????"match_all":?{}
??},
??"sort":?[
????{
??????"FIELD":?"desc"??//?排序字段、排序方式ASC、DESC
????}
??]
}
排序條件是一個(gè)數(shù)組,也就是可以寫多個(gè)排序條件。按照聲明的順序,當(dāng)?shù)谝粋€(gè)條件相等時(shí),再按照第二個(gè)條件排序,以此類推
1.2.地理坐標(biāo)排序
地理坐標(biāo)排序略有不同。
語法說明:
GET?/indexName/_search
{
??"query":?{
????"match_all":?{}
??},
??"sort":?[
????{
??????"_geo_distance"?:?{
??????????"FIELD"?:?"緯度,經(jīng)度", // 文檔中g(shù)eo_point類型的字段名、目標(biāo)坐標(biāo)點(diǎn)
??????????"order"?:?"asc", // 排序方式
??????????"unit"?:?"km" // 排序的距離單位
??????}
????}
??]
}
這個(gè)查詢的含義是:
-
指定一個(gè)坐標(biāo),作為目標(biāo)點(diǎn)
-
計(jì)算每一個(gè)文檔中,指定字段(必須是geo_point類型)的坐標(biāo) 到目標(biāo)點(diǎn)的距離是多少
-
根據(jù)距離排序
2.分頁
elasticsearch 默認(rèn)情況下只返回top10的數(shù)據(jù)。而如果要查詢更多數(shù)據(jù)就需要修改分頁參數(shù)了。elasticsearch中通過修改from、size參數(shù)來控制要返回的分頁結(jié)果:
-
from:從第幾個(gè)文檔開始
-
size:總共查詢幾個(gè)文檔
類似于mysql中的limit ?, ?
2.1.基本的分頁
分頁的基本語法如下:
GET?/hotel/_search
{
??"query":?{
????"match_all":?{}
??},
??"from":?0,?//?分頁開始的位置,默認(rèn)為0
??"size":?10,?//?期望獲取的文檔總數(shù)
??"sort":?[
????{"price":?"asc"}
??]
}
2.2.深度分頁問題
現(xiàn)在,我要查詢990~1000的數(shù)據(jù),查詢邏輯要這么寫:
GET?/hotel/_search
{
??"query":?{
????"match_all":?{}
??},
??"from":?990,?//?分頁開始的位置,默認(rèn)為0
??"size":?10,?//?期望獲取的文檔總數(shù)
??"sort":?[
????{"price":?"asc"}
??]
}
這里是查詢990開始的數(shù)據(jù),也就是 第990~第1000條 數(shù)據(jù)。
不過,elasticsearch內(nèi)部分頁時(shí),必須先查詢 0~1000條,然后截取其中的990 ~ 1000的這10條:
查詢TOP1000,如果es是單點(diǎn)模式,這并無太大影響。
但是elasticsearch將來一定是集群,例如我集群有5個(gè)節(jié)點(diǎn),我要查詢TOP1000的數(shù)據(jù),并不是每個(gè)節(jié)點(diǎn)查詢200條就可以了。
因?yàn)楣?jié)點(diǎn)A的TOP200,在另一個(gè)節(jié)點(diǎn)可能排到10000名以外了。
因此要想獲取整個(gè)集群的TOP1000,必須先查詢出每個(gè)節(jié)點(diǎn)的TOP1000,匯總結(jié)果后,重新排名,重新截取TOP1000。
那如果我要查詢9900~10000的數(shù)據(jù)呢?是不是要先查詢TOP10000呢?那每個(gè)節(jié)點(diǎn)都要查詢10000條?匯總到內(nèi)存中?
當(dāng)查詢分頁深度較大時(shí),匯總數(shù)據(jù)過多,對內(nèi)存和CPU會產(chǎn)生非常大的壓力,因此elasticsearch會禁止from+ size 超過10000的請求。
針對深度分頁,ES提供了兩種解決方案,官方文檔:
-
search after:分頁時(shí)需要排序,原理是從上一次的排序值開始,查詢下一頁數(shù)據(jù)。官方推薦使用的方式。
-
scroll:原理將排序后的文檔id形成快照,保存在內(nèi)存。官方已經(jīng)不推薦使用。
2.3.小結(jié)
分頁查詢的常見實(shí)現(xiàn)方案以及優(yōu)缺點(diǎn):
-
from + size
:-
優(yōu)點(diǎn):支持隨機(jī)翻頁
-
缺點(diǎn):深度分頁問題,默認(rèn)查詢上限(from + size)是10000
-
場景:百度、京東、谷歌、淘寶這樣的隨機(jī)翻頁搜索
-
-
after search
:-
優(yōu)點(diǎn):沒有查詢上限(單次查詢的size不超過10000)
-
缺點(diǎn):只能向后逐頁查詢,不支持隨機(jī)翻頁
-
場景:沒有隨機(jī)翻頁需求的搜索,例如手機(jī)向下滾動(dòng)翻頁
-
-
scroll
:-
優(yōu)點(diǎn):沒有查詢上限(單次查詢的size不超過10000)
-
缺點(diǎn):會有額外內(nèi)存消耗,并且搜索結(jié)果是非實(shí)時(shí)的
-
場景:海量數(shù)據(jù)的獲取和遷移。從ES7.1開始不推薦,建議用 after search方案。
-
3.高亮
3.1.高亮原理
什么是高亮顯示呢?
我們在百度,京東搜索時(shí),關(guān)鍵字會變成紅色,比較醒目,這叫高亮顯示:
高亮顯示的實(shí)現(xiàn)分為兩步:
-
1)給文檔中的所有關(guān)鍵字都添加一個(gè)標(biāo)簽,例如
<em>
標(biāo)簽 -
2)頁面給
<em>
標(biāo)簽編寫CSS樣式
3.2.實(shí)現(xiàn)高亮
高亮的語法:
GET?/hotel/_search
{
??"query":?{
????"match":?{
??????"FIELD":?"TEXT" // 查詢條件,高亮一定要使用全文檢索查詢
????}
??},
??"highlight":?{
????"fields":?{?//?指定要高亮的字段
??????"FIELD":?{
????????"pre_tags":?"<em>",??//?用來標(biāo)記高亮字段的前置標(biāo)簽
????????"post_tags":?"</em>"?//?用來標(biāo)記高亮字段的后置標(biāo)簽
??????}
????}
??}
}
注意:
-
高亮是對關(guān)鍵字高亮,因此搜索條件必須帶有關(guān)鍵字,而不能是范圍這樣的查詢。
-
默認(rèn)情況下,高亮的字段,必須與搜索指定的字段一致,否則無法高亮
-
如果要對非搜索字段高亮,則需要添加一個(gè)屬性:required_field_match=false
4.總結(jié)
查詢的DSL是一個(gè)大的JSON對象,包含下列屬性:
-
query:查詢條件
-
from和size:分頁條件
-
sort:排序條件文章來源:http://www.zghlxwxcb.cn/news/detail-789519.html
-
highlight:高亮條件文章來源地址http://www.zghlxwxcb.cn/news/detail-789519.html
到了這里,關(guān)于es的搜索結(jié)果處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!