ES提供了豐富多彩的查詢接口,可以滿足各種各樣的查詢要求。更多內容請參考: ELK修煉之道
Query DSL結構化查詢
- Query DSL是一個Java開源框架用於構建類型安全的SQL查詢語句。采用API代替傳統的拼接字符串來構造查詢語句。目前Querydsl支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。
- elasticsearch提供了一整套基於JSON的查詢DSL語言來定義查詢。
- Query DSL當作是一系列的抽象的查詢表達式樹(AST)特定查詢能夠包含其它的查詢,(如 bool ), 有些查詢能夠包含過濾器(如 constant_score), 還有的可以同時包含查詢和過濾器 (如 filtered). 都能夠從ES支持查詢集合里面選擇任意一個查詢或者是從過濾器集合里面挑選出任意一個過濾器, 這樣的話,我們就可以構造出任意復雜(maybe 非常有趣)的查詢了,是不是很靈活啊。
舉個例子
GET _search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "20150101" }}}
]
}
}
}
查詢的分類
Leaf query Cluase 葉子查詢(簡單查詢)
這種查詢可以單獨使用,針對指定的字段查詢指定的值。
Compound query clauses 復雜查詢
復雜查詢可以包含葉子或者其它的復雜查詢語句,用於組合成復雜的查詢語句,比如not, bool等。
**
查詢雖然包含這兩種,但是查詢的行為還與查詢的執行環境有關,不同的執行環境,查詢操作也不一樣。**
查詢的行為取決於他們所在的查詢上下文,包括Query查詢上下文和Filter查詢上下文。
查詢與過濾
-
Query查詢上下文
在Query查詢上下文中,查詢會回答這個問題--"這個文檔匹不匹配查詢條件,它的相關性高么?"
除了決定文檔是夠匹配,針對匹配的文檔,查詢語句還會計算一個_score相關性分值,分數越高,匹配度越高,默認返回是越靠前。這里關於分值的計算不再介紹,以后再做介紹。 -
Filter過濾器上下文
在Filter過濾器上下文中,查詢會回答這個問題--"這個文檔是否匹配"
這個結果要么“不是”要么“是”,不會計算分值問題,也不會關心返回的排序問題,這樣性能方面就比Query查詢高了。Filter過濾器主要用於過濾結構化數據,例如:- 時間戳范圍是否在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" }}}
]
}
}
}
性能差異
使用過濾語句得到的結果集———一個簡單的文檔列表,快速匹配運算並存入內存是非常方便的,每個文檔僅需1個字節。這些緩存的過濾結果集與后續請求的結合使用時非常高效的。
查詢語句不僅要查找相匹配的文檔,還需要計算每個文檔的相關性,所以一般來說查詢語句要比過濾語句更耗時,並且查詢結果也不可緩存。
幸虧有了倒排索引,一個只匹配少量文檔的簡單查詢語句在百萬級文檔中的查詢效率會與一條經過緩存的過濾語句旗鼓相當,甚至略占上風。但是一般情況下,一條經過緩存的過濾查詢要遠勝一條查詢語句的執行效率。
總結
- Query查詢上下文中,查詢操作會根據查詢的結果進行相關性分值計算,用於確定相關性。分值越高,返回的結果越靠前。
- Filter過濾器上下文中,查詢不會計算相關性分值,也不會對結果進行排序。
- 過濾器上下文中,查詢的結果可以被緩存。
以后博客中提到的查詢就是在Query查詢上下文,過濾就是指filter過濾器上下文。- 原則上來說,使用查詢語句做全文本搜索或其他需要進行相關性評分的時候,剩下的全部用過濾語句
參考
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html
