本文已参与「新人创作礼」活动,一起开启掘金创作之路。
复合查询
使用bool查询
接受以下参数:
- must:文档必须匹配设定条件才能被包含进来
- must_not:文档必须不匹配设定条件才能被包含进来
- should:如果满足语句中的任意语句,将增加_source,否则,无任何影响。主要用于修正每个文档的相关性得分
- filter:必须匹配,但以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档
相关性得分是如何组合的?
每一个子查询都独自的计算文档的相关性得分,bool查询将对计算出的等分进行合并,然后返回一个代表整个布尔操作的等分。
下面的查询用于查找title字段匹配 how to make millions 并且不被标识为 spam的文档。那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名。如果 两者 都满足,那么它的排名将更高。
GET /lib3/user/_search
{
"query": {
"bool": {
"must": {
"match": {
"interests": "changge"
}
},
"must_not": {
"match": {
"interests": "lvyou"
}
},
"should": [
{
"match": {
"address": "bei jing"
}
},
{
"range": {
"birthday": {
"gte": "1996-01-01"
}
}
}
]
}
}
}
如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。但如果存在至少一条 must 语句,则对 should 语句的匹配没有要求。如果不想因为文档的时间影响得分,可以用 filter 语句来重写前面的例子
# 可以在bool内嵌套filter过滤
GET /lib3/user/_search
{
"query": {
"bool": {
"must": {
"match": {
"interests": "changge"
}
},
"must_not": {
"match": {
"interests": "lvyou"
}
},
"should": [
{
"match": {
"address": "bei jing"
}
}
],
"filter": {
"range": {
"birthday": {
"gte": "1996-01-01"
}
}
}
}
}
}
通过将 range 查询移动到 filter 语句中,我们将它转成不评分的查询,将不在影响文档的相关性排名,由于它现在是一个不评分的查询,可以使用各种对 filter 查询有效的优化手段来提升性能。
bool 查询本身也可以被用作不评分的查询,简单的将它放置到 filter 语句中并在内部构建布尔逻辑
# 在bool内嵌套fliter,在fliter下嵌套另一个bool作为过滤条件
GET /lib3/user/_search
{
"query": {
"bool": {
"must": {
"match": {
"interests": "changge"
}
},
"must_not": {
"match": {
"interests": "lvyou"
}
},
"should": [
{
"match": {
"address": "bei jing"
}
}
],
"filter": {
"bool": {
"must": [
{
"range": {
"birthday": {
"gte": "1990-01-01"
}
}
},
{
"range": {
"age": {
"lte": 30
}
}
}
],
"must_not": [
{
"term": {
"age": "29"
}
}
]
}
}
}
}
}
constant_score查询
constant_score将一个不变的量评分应用于所有匹配的文档,被经常用于你只需要执行一个 fliter 而没有其他查询(例如:评分查询)的情况下。 请求结构如下:
{
"constant_score": {
"filter": {
"term": {
"category": "ebooks"
}
}
}
}
示例:
GET /lib4/items/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"interests": "changge"
}
}
}
}
}
term 查询被放置在constant_score中,转成不评分的 filter。这种方式可以用来取代只有 filter 语句的 bool 查询。