Elasticsearch(入门篇)——Query DSL与查询行为

ES提供了丰富多彩的查询接口,能够知足各类各样的查询要求。更多内容请参考: ELK修炼之道

Query DSL结构化查询

  • Query DSL是一个Java开源框架用于构建类型安全的SQL查询语句。采用API代替传统的拼接字符串来构造查询语句。目前Querydsl支持的平台包括JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。
  • elasticsearch提供了一整套基于JSON的查询DSL语言来定义查询。
  • Query DSL看成是一系列的抽象的查询表达式树(AST)特定查询可以包含其它的查询,(如 bool ), 有些查询可以包含过滤器(如 constant_score), 还有的能够同时包含查询和过滤器 (如 filtered). 都可以从ES支持查询集合里面选择任意一个查询或者是从过滤器集合里面挑选出任意一个过滤器, 这样的话,咱们就能够构造出任意复杂(maybe 很是有趣)的查询了,是否是很灵活啊。

举个例子html

GET _search
{
    "query": {
        "bool": {
            "must": [
                { "match": { "title": "Search" }},
                { "match": { "content": "Elasticsearch" }}
            ],
            "filter": [
                { "term": { "status": "published" }},
                { "range": { "publish_date": { "gte": "2015­01­01" }}}
            ]
        }
    }
}

查询的分类 json

Leaf query Cluase 叶子查询(简单查询)
这种查询能够单独使用,针对指定的字段查询指定的值。缓存

Compound query clauses 复杂查询
复杂查询能够包含叶子或者其它的复杂查询语句,用于组合成复杂的查询语句,好比not, bool等。安全


查询虽然包含这两种,可是查询的行为还与查询的执行环境有关,不一样的执行环境,查询操做也不同。

查询的行为取决于他们所在的查询上下文,包括Query查询上下文和Filter查询上下文。框架

查询与过滤

  • Query查询上下文
    在Query查询上下文中,查询会回答这个问题--"这个文档匹不匹配查询条件,它的相关性高么?"
    除了决定文档是够匹配,针对匹配的文档,查询语句还会计算一个_score相关性分值,分数越高,匹配度越高,默认返回是越靠前。这里关于分值的计算再也不介绍,之后再作介绍。elasticsearch

  • Filter过滤器上下文
    在Filter过滤器上下文中,查询会回答这个问题--"这个文档是否匹配"
    这个结果要么“不是”要么“是”,不会计算分值问题,也不会关心返回的排序问题,这样性能方面就比Query查询高了。Filter过滤器主要用于过滤结构化数据,例如:
    • 时间戳范围是否在2015-2016之间?
    • status字段是否被设置成"published"?
      另外,经常使用的过滤器会自动缓存Elasticsearch,加速性能。

举个简单的例子:ide

  1. title字段包含关键词"search"
  2. content字段包含关键词"elasticsearch"
  3. status字段存在精确词"published"
  4. publish_date字段包含一个日期由2015年1月1日起
GET _search
{
  "query": { 
    "bool": { 
      "must": [
        { "match": { "title":   "Search"        }}, 
        { "match": { "content": "Elasticsearch" }}  
      ],
      "filter": [ 
        { "term":  { "status": "published" }}, 
        { "range": { "publish_date": { "gte": "2015-01-01" }}} 
      ]
    }
  }
}

性能差别
使用过滤语句获得的结果集———一个简单的文档列表,快速匹配运算并存入内存是很是方便的,每一个文档仅需1个字节。这些缓存的过滤结果集与后续请求的结合使用时很是高效的。
查询语句不只要查找相匹配的文档,还须要计算每一个文档的相关性,因此通常来讲查询语句要比过滤语句更耗时,而且查询结果也不可缓存。
幸好有了倒排索引,一个只匹配少许文档的简单查询语句在百万级文档中的查询效率会与一条通过缓存的过滤语句旗鼓至关,甚至略占上风。可是通常状况下,一条通过缓存的过滤查询要远胜一条查询语句的执行效率。性能

总结

  1. Query查询上下文中,查询操做会根据查询的结果进行相关性分值计算,用于肯定相关性。分值越高,返回的结果越靠前。
  2. Filter过滤器上下文中,查询不会计算相关性分值,也不会对结果进行排序。
  3. 过滤器上下文中,查询的结果能够被缓存。
  4. 之后博客中提到的查询就是在Query查询上下文,过滤就是指filter过滤器上下文。
  5. 原则上来讲,使用查询语句作全文本搜索或其余须要进行相关性评分的时候,剩下的所有用过滤语句

参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.htmlui

相关文章
相关标签/搜索