Elasticsearch过滤查询与过滤器的区别

49

“在 filtered 中的查询和过滤”与“在根节点上的查询和过滤”之间有区别吗?

例如,情况1:

{
  "query":{
    "filtered":{
      "query":{
        "term":{"title":"kitchen3"}
      },
      "filter":{
        "term":{"price":1000}
      }
    }
  }
}

情况2:

{
  "query":{
    "term":{"title":"kitchen3"}
  },
  "filter":{
    "term":{"price":1000}
  }
}

我发现了这个讨论:http://elasticsearch-users.115913.n3.nabble.com/Filtered-query-vs-using-filter-outside-td3960119.html,但是引用的链接是404,而且其中的解释对我来说有点过于简洁。

请教或提供任何指向这两者之间区别的文档,谢谢。


6
https://dev59.com/r14b5IYBdhLWcg3wlihP - Dan Tuffery
2021年更新,对于ES > 6.8版本,过滤查询被布尔查询所取代。 - Ansuman
2个回答

42

两者的区别与性能有关。在顶级的"filter"总是在查询之后执行。这意味着查询在所有文档上执行,对于所有文档计算得分等等-然后才排除不匹配过滤条件的文档。

使用"filtered"查询有可能让ES优化这个计算过程,例如首先执行过滤器,然后在有限的文档集上执行查询,节省测试不符合查询且得分为0的文档的时间,如果它们匹配查询,则同时节省计算它们的得分的时间。

如果您使用相同的过滤器执行多个查询,则还有更多的优势:过滤器可以被缓存,进一步提高每个查询的性能。这适用于您的示例:"term"过滤器默认情况下是被缓存的。

您还可以明确控制"filtered"查询的执行方式(请参见文档),以优化它以适应您特定的用例。


请问在过滤查询中,如果我在query之前添加了filter,这会对性能有所影响吗? - Sudhanshu Gaur
1
@SudhanshuGaur,查询JSON中键的顺序不影响结果。但你可以控制过滤策略,从而影响性能: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html#_filter_strategy - Alexey Tigarev

9

这两种类型的过滤器可以称为预过滤器和后置过滤器。根据@alexey所述,根级别的过滤器在查询和过滤之后执行,而"filtered"查询中的过滤器在查询之前执行。

此外,您需要理解它们执行顺序以外的影响。"filtered"查询中的过滤器属于查询范围,这意味着在计算聚合时,过滤器输出将被考虑,而在根级别过滤器中,聚合仅针对查询结果进行,不包括过滤器。虽然在两种情况下,结果文档将是相同的。

例如,对于您发布的两个查询,两者都会给出相同的结果,但如果您还执行聚合,第一个查询将从匹配标题为kitchen3且价格为10000的文档计算聚合计数,而第二个查询将仅从匹配标题为kitchen3的文档计算聚合计数,而不包括价格1000的过滤器。


1
"过滤器在过滤查询之前执行" - Alexey Tigarev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接