查询vs过滤器以及查询或过滤器中正确表达的用法

Avn*_*arr 2 lucene elasticsearch elasticsearch-dsl

我在SO中看到了很多问题,还阅读了有关“未缓存查询时缓存了过滤器”的文档,以及“对所有值应用查询”和“如果查询对象之外在查询后应用了过滤器”等信息, 。

底线是文档很烂,DSL很难掌握。我正在尝试优化一些查询并使用kibana dev工具搜索分析器,但是我的本地数据集必须太小,无法测量实际的性能差异(我正在双向获得结果),并且没有测试具有多个节点的集群,以处理真实的大型数据集。

在这种情况下,所有查询将返回相同的结果。我想了解两者之间的区别,以及在任何允许将子句放置在过滤器中的情况下,为什么您更喜欢查询而不是过滤器

GET foo11/_search
{
  "query": {
    "bool": {
      "filter": {
        "match" : {
          "in_stock" : true
        }
      }
    }
  }
}

GET foo11/_search
{
  "query": {
    "bool": {
      "filter": {
        "term" : {
          "in_stock" : true
        }
      }
    }
  }
}


GET foo11/_search
{
  "query": {
    "bool": {
      "must": {
        "match" : {
          "in_stock" : true
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这3种情况在表现上有什么区别?我真的可以证明一个比另一个更好/更差吗?

之间有什么区别?

"match" : {
  "in_stock" : true
}
Run Code Online (Sandbox Code Playgroud)

"term" : {
  "in_stock" : true
}
Run Code Online (Sandbox Code Playgroud)

Rya*_*ier 5

有几个不同的问题和概念需要解开。

比赛对词

一个match查询进行分析,在指数寻找它之前(去除共停用词,词干除去尾随“荷兰国际集团”,“ES”等),您提供的搜索值。分析的目的是使含义大致相同的单词匹配,例如,如果您搜索“ bananas”但索引了“ banana”,它仍然会找到它。值得注意的是,要执行此分析,索引数据时还必须在字段上进行ALSO,这就是textElasticsearch中的类型字段所做的事情。

term查询,是不进行任何分析的精确匹配。这更像您将在关系数据库中使用的样子。这些是针对keyword字段和其他数据类型字段(数字,布尔值,日期)而执行的。如果您需要同时匹配两种方式,则可以使用两种类型对字段进行索引。

查询与过滤

一个query在elasticsearch是一系列将被拿下,并针对对方根据他们的相关性排名的搜索条款。换句话说,根据您要我搜索的单词,哪些文档似乎最相关。

一个filter在elasticsearch限制记录组针对该查询运行并没有预制棒得分。您可以将其视为第一步,它确定了在进行更昂贵的计算以确定搜索词与每个文档的相关性之前,要检查哪些记录。

您提到的另一个重要区别是filters已缓存,但未缓存queries。通常,如果您要应用广泛的条件,则可以设置这些过滤器,并使“人工文本”搜索部分成为查询。一般而言,如果您有广泛的限制,则可以限制可搜索的文档集,可以将其放入过滤器中,以利用缓存和节省时间避免记分。例如,类似的内容:仅过滤食谱中的产品,然后查询带有香蕉一词的标题。

绩效评估

衡量查询性能可能很困难,因为混合中有很多活动部件。如果有时间,最好的方法是将代表性(且数量较大)的数据索引到单个节点,然后在扩展之前针对该数据进行初始测试。您可能还需要查看Elasticsearch的性能测试工具Rally。

https://github.com/elastic/rally

放在一起

对于上面的示例,由于您要搜索的字段是布尔值,因此您想执行term查询而不是match查询。另外,您可以在filter子句中执行此操作,因为没有针对单个布尔值的相关性评分。如果您想将其与其他文本搜索结合使用,则可以在query上下文中向您的json主体添加match子句。