前言
ES提供了豐富多彩的查詢接口羽峰,可以滿足各種各樣的查詢要求合愈。更多內(nèi)容請參考:<a href="">ELK修煉之道</a>
</blockquote>
Query DSL結(jié)構(gòu)化查詢
- Query DSL是一個Java開源框架用于構(gòu)建類型安全的SQL查詢語句陌选。采用API代替?zhèn)鹘y(tǒng)的拼接字符串來構(gòu)造查詢語句波附。目前Querydsl支持的平臺包括JPA,JDO,SQL,Java Collections溃论,RDF,Lucene痘昌,Hibernate Search钥勋。
- elasticsearch提供了一整套基于JSON的查詢DSL語言來定義查詢。
- Query DSL當作是一系列的抽象的查詢表達式樹(AST)特定查詢能夠包含其它的查詢辆苔,(如 bool ), 有些查詢能夠包含過濾器(如 constant_score), 還有的可以同時包含查詢和過濾器 (如 filtered). 都能夠從ES支持查詢集合里面選擇任意一個查詢或者是從過濾器集合里面挑選出任意一個過濾器, 這樣的話算灸,我們就可以構(gòu)造出任意復雜(maybe 非常有趣)的查詢了,是不是很靈活啊姑子。
舉個例子
GET _search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "2015-01-01" }}}
]
}
}
}
<p style="color:red">查詢的分類 </p>
Leaf query Cluase 葉子查詢(簡單查詢)
這種查詢可以單獨使用乎婿,針對指定的字段查詢指定的值。
Compound query clauses 復雜查詢
復雜查詢可以包含葉子或者其它的復雜查詢語句街佑,用于組合成復雜的查詢語句谢翎,比如not, bool等。
**
查詢雖然包含這兩種沐旨,但是查詢的行為還與查詢的執(zhí)行環(huán)境有關森逮,不同的執(zhí)行環(huán)境,查詢操作也不一樣磁携。**
查詢的行為取決于他們所在的查詢上下文褒侧,包括Query查詢上下文和Filter查詢上下文。
查詢與過濾
Query查詢上下文
在Query查詢上下文中谊迄,查詢會回答這個問題--<strong style="color:red">"這個文檔匹不匹配查詢條件闷供,它的相關性高么?"</strong>
除了決定文檔是夠匹配统诺,針對匹配的文檔歪脏,查詢語句還會計算一個<code>_score</code>相關性分值,分數(shù)越高粮呢,匹配度越高婿失,默認返回是越靠前。這里關于分值的計算不再介紹啄寡,以后再做介紹豪硅。-
Filter過濾器上下文
在Filter過濾器上下文中,查詢會回答這個問題--<strong style="color:red">"這個文檔是否匹配"</strong>
這個結(jié)果要么“不是”要么“是”挺物,不會計算分值問題懒浮,也不會關心返回的排序問題,這樣性能方面就比Query查詢高了。Filter過濾器主要用于過濾結(jié)構(gòu)化數(shù)據(jù)识藤,例如:- 時間戳范圍是否在2015-2016之間嵌溢?
- status字段是否被設置成"published"?
另外眯牧,常用的過濾器會自動緩存Elasticsearch,加速性能蹋岩。
舉個簡單的例子:
- title字段包含關鍵詞"search"
- content字段包含關鍵詞"elasticsearch"
- status字段存在精確詞"published"
- publish_date字段包含一個日期由2015年1月1日起
GET _search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "2015-01-01" }}}
]
}
}
}
性能差異
使用過濾語句得到的結(jié)果集———一個簡單的文檔列表赖草,快速匹配運算并存入內(nèi)存是非常方便的,每個文檔僅需1個字節(jié)剪个。這些緩存的過濾結(jié)果集與后續(xù)請求的結(jié)合使用時非常高效的秧骑。
查詢語句不僅要查找相匹配的文檔,還需要計算每個文檔的相關性扣囊,所以一般來說查詢語句要比過濾語句更耗時乎折,并且查詢結(jié)果也不可緩存。
幸虧有了倒排索引侵歇,一個只匹配少量文檔的簡單查詢語句在百萬級文檔中的查詢效率會與一條經(jīng)過緩存的過濾語句旗鼓相當骂澄,甚至略占上風。但是一般情況下惕虑,一條經(jīng)過緩存的過濾查詢要遠勝一條查詢語句的執(zhí)行效率坟冲。
總結(jié)
- Query查詢上下文中,查詢操作會根據(jù)查詢的結(jié)果進行相關性分值計算溃蔫,用于確定相關性健提。分值越高,返回的結(jié)果越靠前伟叛。
- Filter過濾器上下文中私痹,查詢不會計算相關性分值,也不會對結(jié)果進行排序统刮。
- 過濾器上下文中紊遵,查詢的結(jié)果可以被緩存。
- <code style="color:red">以后博客中提到的查詢就是在Query查詢上下文侥蒙,過濾就是指filter過濾器上下文暗膜。</code>
- 原則上來說,使用查詢語句做全文本搜索或其他需要進行相關性評分的時候辉哥,剩下的全部用過濾語句
參考
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html