查询语法(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
}
}
}
}
}
}
答案是处于过滤上下文,上下文的判断基于顶层语句