组合多查询


现实的查询需求从来都没有那么简单;它们需要在多个字段上查询多种多样的文本,并且根据一系列的标准来过滤。为了构建类似的高级查询,你需要一种能够将多查询组合成单一查询的查询方法。


你可以用 bool

must


文档 必须


must_not


文档 必须不


should

如果满足这些语句中的任意语句,将增加 _score

filter


必须


由于这是我们看到的第一个包含多个查询的查询,所以有必要讨论一下相关性得分是如何组合的。每一个子查询都独自地计算文档的相关性得分。一旦他们的得分被计算出来, bool

下面的查询用于查找 title 字段匹配 how to make millions 并且不被标识为 spam 的文档。那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名。如果 两者

{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }},
            { "range": { "date": { "gte": "2014-01-01" }}}
        ]
    }
}


Tip

如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。但,如果存在至少一条 must 语句,则对 should


增加带过滤器(filtering)的查询


如果我们不想因为文档的时间而影响得分,可以用 filter


{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }}
        ],
        "filter": {
          "range": { "date": { "gte": "2014-01-01" }} (1)
        }
    }
}



  1. range 查询已经从 

should

  1.  语句中移到 

filter

通过将 range 查询移到 filter

所有查询都可以借鉴这种方式。将查询移到 bool 查询的 filter

如果你需要通过多个不同的标准来过滤你的文档,bool 查询本身也可以被用做不评分的查询。简单地将它放置到 filter


{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }}
        ],
        "filter": {
          "bool": { (1)
              "must": [
                  { "range": { "date": { "gte": "2014-01-01" }}},
                  { "range": { "price": { "lte": 29.99 }}}
              ],
              "must_not": [
                  { "term": { "category": "ebooks" }}
              ]
          }
        }
    }
}



  1. 将 

bool

  1.  查询包裹在 

filter


通过混合布尔查询,我们可以在我们的查询请求中灵活地编写 scoring 和 filtering 查询逻辑。


constant_score 查询


尽管没有 bool 查询使用这么频繁,constant_score

可以使用它来取代只有 filter 语句的 bool


{
    "constant_score":   {
        "filter": {
            "term": { "category": "ebooks" } (1)
        }
    }
}


term

  1.  查询被放置在 

constant_score

  1.  中,转成不评分的 filter。这种方式可以用来取代只有 filter 语句的 

bool