查詢語法(Query DSL)
Elasticsearch提供標準RESTful風格的查詢DSL來定義查詢。可以將查詢 DSL 看作是由兩種子句組成的查詢的 AST (Abstract Syntax Tree) :
Leaf query clauses
葉查詢語句(可以理解爲SQL裏的where查詢)在特定字段中查找特定值,例如 match,term或 range查詢,這些查詢同時也可以單獨使用。
Compound query clauses
複合查詢語句可以組合Leaf Query和Compound Query,用於以組合多個查詢 ,或者更改其行爲(例如 constant_score查詢)。
查詢語句行爲的不同取決於它們是在查詢上下文還是過濾器上下文中使用。
查詢上下文和過濾上下文
查詢子句的行爲取決於它是在查詢上下文中使用還是在過濾上下文中使用:
查詢上下文
在查詢上下文中使用的查詢子句會回答這個問題:“此文檔與此查詢子句的匹配程度怎麼樣?” 除了決定文檔是否匹配之外,查詢子句還會計算一個評分,用來表示文檔的匹配度。
只要將查詢子句傳遞給query
參數(比如Search API 中的query
參數) ,查詢上下文就會生效。
過濾上下文
在過濾上下文中,查詢子句回答以下問題:"此文檔與此查詢子句匹配嗎?" 答案只有是或否,不計算評分。 過濾上下文主要用於過濾結構化的數據,例如:
- 這個時間是否在2015到2016年之間?
- 狀態是不是已發佈?
經常使用的過濾器將被 Elasticsearch 自動緩存,以提高性能。
只要將查詢子句傳遞給filter
(如 bool
查詢中的 filter
或 must not
,constant_score
查詢中的 filter
或aggregation
中的filter
) ,過濾上下文就會生效。
一些例子
那怎麼判斷自己的dsl是查詢上下文還是過濾上下文呢?以下給出一些解釋
基礎查詢都屬於查詢上下文
{
"query":{
"term/range/terms/match/match_phrase":{}
}
}
constant_score比較特殊,雖然看着是基礎查詢,但是他是固定評分查詢,所以也屬於過濾上下文
{
"query":{
"constant_score":{}
}
}
bool查詢中的filter屬於過濾上下文
{
"query":{
"bool":{
//filter這裏可以定義對象,單個過濾子句,也可以定義數組,多個過濾條件
"filter":[]
"filter":{}
}
}
}
bool查詢中的must not屬於過濾上下文
{
"query":{
"bool":{
"mustnot":[]
}
}
}
agg聚合查詢中的filter agg也屬於過濾上下文
{
"aggs":{
"t_shirts" : {
"filter" : { "term": { "type": "t-shirt" } },
"aggs" : {
"avg_price" : { "avg" : { "field" : "price" } }
}
}
}
}
那麼問題來了,如果我在bool/filter中嵌套了boolean/must子句,那這裏的must子句到底是查詢上下文還是過濾上下文呢?
{
"query":{
"bool":{
"filter":{
"bool":{
"must":{
//query cause
}
}
}
}
}
}
答案是處於過濾上下文,上下文的判斷基於頂層語句