查询与过滤

两者之间的性能差异:

过滤查询只是简单的检查包含或者排除,这使得计算起来非常快。考虑到至少有一个过滤查询的结果是稀少的,并且经常使用不评分查询,结果会被缓存到内存中以便快速读取。

评分查询不仅仅要找出匹配的文档,还要计算每个匹配文档的相关性,计算相关性使得它们比不评分查询费力的多。

过滤的目标是减少哪些需要通过评分查询进行检查的文档。

适用场景:通常查询语句来进行全文搜索或者其他任何需要影响相关性得分的搜索。除此之外的情况都适用过滤。

最重要的查询

match_all查询

匹配所有文档,没有指定查询方式时,它是默认的查询

{
  "match_all":{}
}

经常和filter结合使用。

match查询

精确查询和全文搜索都是适用的。如果在一个全文字段上适用Match,在执行查询之前,它将用正确的分析器去分析查询字符串。
如果在一个精确值的字段使用它,那么它将会精确匹配给定的值。

{ "match": { "age":    26           }}
{ "match": { "date":   "2014-09-01" }}
{ "match": { "public": true         }}
{ "match": { "tag":    "full_text"  }}

精确值的查询,可以使用filter进行取代,因为filter将会被缓存。

multi_match查询

multi_match查询可以在多个字段上执行相同的match查询:

{
    "multi_match": {
        "query":    "full text search",
        "fields":   [ "title", "body" ]
    }
}

range查询

查询找出落在指定区间内的数字或者时间:

{
    "range": {
        "age": {
            "gte":  20,
            "lt":   30
        }
    }
}

term查询

term查询被用于精确值匹配,这些精确值可以是数字、时间、布尔或者那些 not_analyzed 的字符串。 不会被查询输入的文本进行分析。

{ "term": { "age":    26           }}
{ "term": { "date":   "2014-09-01" }}
{ "term": { "public": true         }}
{ "term": { "tag":    "full_text"  }}

terms查询

terms查询和term查询一样,但是它允许指定多值进行匹配。

{
   "terms": { 
   "tag": [ "search", "full_text", "nosql" ] 
   }
 }

exists查询和missing查询

exists查询和missing查询被用于查询那些指定字段有值或无值的文档。

{
    "exists":   {
        "field":    "title"
    }
}

组合多查询

使用bool查询将多查询组合起来。它接受以下的参数

  • must:文档必须匹配这些条件才能被包含进来。
  • must_not:文档必须不匹配这些条件才能被包含进来。
  • should:如果满足这些语句中的任意语句,将增加_score,否则无影响。
  • filter:必须匹配,但以不评分、过滤模式来进行。

每一个子查询都独自地计算文档的相关性得分。一旦他们的得分被计算出来, bool 查询就将这些得分进行合并并且返回一个代表整个布尔操作的得分。

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

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

带过滤器的查询

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

constant_score查询

constant_score查询将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个filter而没有其他查询的情况下。

{
    "constant_score":   {
        "filter": {
            "term": { "category": "ebooks" } 
        }
    }
}

term查询被放置在constant_score中,转成不评分的filter.这种方式可以用来取代只有filter的bool查询。

验证查询

可以使用validate-query Api用来验证查询是否合法。

GET /gb/tweet/_validate/query
{
   "query": {
      "tweet" : {
         "match" : "really powerful"
      }
   }
}

# 显示错误信息
GET /gb/tweet/_validate/query?explain 
{
   "query": {
      "tweet" : {
         "match" : "really powerful"
      }
   }
}

更多推荐