ES 支持类似于在SQL中使用 AND
、OR
以及 NOT
的运算, 称之为布尔查询(Boolean Query),如:
[1] - must
:文档必须符合其中所有的查询条件,包含多个条件时类似于SQL中的AND
[2] - should
:文档必须符合其中任意一个及以上查询条件(可由minimum_should_match
指定需要满足的条件数量),包含多个条件时类似于SQL中的OR
[3] - must_not
:文档必须不符合其中所有的查询条件,类似于SQL中的NOT
,且返回的结果的分值都为0
[4] - filter
:效果与使用must
相同,但不影响查询结果的分值(score)
ES 使用布尔查询时,需要将查询的条件写在bool查询语句中,且同个bool查询语句可以有多个不同的条件,如:
{
"query": {
"bool": {
"must": {
"term": {
"age": 20
}
},
"must_not": {
"term": {
"gender": "male"
}
}
}
}
}
该查询是,返回 age 值为 20,且 gender 值不为 male 的文档结果.
其等同于:
SELECT * FROM xxx WHERE age = 20 AND gender != "male";
1. must 查询
当使用 must
查询时,文档必须符合其中包括的所有查询条件.
当must
查询只包括一个查询条件时,可在DSL(Domain Specific Language,即 ES 使用的结构化查询语言)中使用JSON对象的形式表示,如:
{
"query": {
"bool": {
"must": {
"term": {
"age": 20
}
}
}
}
}
其等同于:
SELECT * FROM xxx WHERE age = 20;
使用must
时可以同时指定多个查询条件,在DSL中它以数组的形式表示,效果类似于SQL中的AND
运算,如:
{
"query": {
"bool": {
"must": [
{ "term": { "age": 20 } },
{ "term": { "gender": "male" } }
]
}
}
}
其等同于:
SELECT * FROM xxx WHERE age = 20 AND gender = "male";
2. fliter 查询
使用 filter
查询时其效果等同于 must
查询,但不同于 must
查询的是,filter
查询不参与查询结果的分值计算,它返回的文档的分值始终为0.
filter
的使用场景适合于过滤不需要的文档,但又不影响最终计算的得分.
如:
{
"query": {
"bool": {
"filter": {
"term": {
"status": "active"
}
}
}
}
}
该查询是,返回所有 status 的值为"active"的文档,其得分均为0.0.
3. should 查询
should
查询类似于SQL中的OR
语句,当其中包括两个及两个以上的条件时,其查询的结果必须至少满足其中一个.
当只有一个查询条件时,即结果必须满足该条件,如:
{
"query": {
"bool": {
"should": [
{ "term": { "age": 20 } },
{ "term": { "gender": "male" } },
{ "range": { "height": { "gte": 170 } } },
]
}
}
}
其等同于:
SELECT * FROM xxx WHERE age = 20 OR gender = "male" or height >= 170;
should
查询与SQL中的OR
运算较为不同的一点是,should
查询可以使用 minimum_should_match
参数指定至少需要满足几个条件. 例如,查询的结果需要满足两个或两个以上的查询条件:
{
"query": {
"bool": {
"should": [
{ "term": { "age": 20 } },
{ "term": { "gender": "male" } },
{ "term": { "height": 170 } },
],
"minimum_should_match": 2
}
}
}
在同一个 bool 语句中若不存在 must
或 filter
时,minimum_should_match
默认的值为1,即至少要满足其中一个条件;但若有其它 must
或 filter
存在时,minimum_should_match
默认值为0。
例如,所有返回的文档age值必定为20,但其中可能包括有status值不为"active"的文档. 若需要二者同时生效,可在bool查询中增加一个参数"minimum_should_match": 1.
{
"query": {
"bool": {
"must": {
"term": {
"age": 20
},
},
"should": {
"term": {
"status": "active"
}
}
}
}
}
4. must_not 查询
must_not
查询类似于SQL语句中的NOT
运算,它将只返回不满足指定条件的文档. 例如:
{
"query": {
"bool": {
"must_not": [
{ "term": { "age": 20 } },
{ "term": { "gender": "male" } }
]
}
}
}
其等同于:
SELECT * FROM xxx WHERE age != 20 AND gender != "male";
另外,must_not
与filter
相同,采用过滤器执行而不需要计算文档的得分,所以返回的结果对应的分值为0.
5. 布尔组合查询
ES 也可以在各个查询中进行嵌套查询. 但需要注意的是,布尔查询必须包含在bool
查询语句中,所以在嵌套查询中必须在内部再次使用bool
查询语句.
如:
{
"query": {
"must": [
{
"bool": {
"should": [
{ "term": { "age": 20 } },
{ "term": { "age": 25 } }
]
}
},
{
"range": {
"level": {
"gte": 3
}
}
}
]
}
}
其等同于:
SELECT * FROM xxx WHERE (age = 20 OR age = 25) AND level >= 3;
再如:
POST _search
{
"query": {
"bool" : {
"must" : {
"term" : { "user.id" : "kimchy" }
},
"filter": {
"term" : { "tags" : "production" }
},
"must_not" : {
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
},
"should" : [
{ "term" : { "tags" : "env1" } },
{ "term" : { "tags" : "deployed" } }
],
"minimum_should_match" : 1,
"boost" : 1.0
}
}
}