Elasticsearch已过滤查询与过滤器

时间:2015-03-10 08:17:41

标签: elasticsearch

"查询和筛选过滤"之间是否有任何区别和"查询和过滤根"?例如

案例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,对我来说解释有点过于简洁。

请教导或给出任何指出这些之间差异的文件,谢谢。

2 个答案:

答案 0 :(得分:39)

差异与表现有关。顶级的“过滤器”始终在>查询后执行。这意味着将对所有文档执行查询,计算所有文档的分数等 - 并且仅排除不匹配过滤器的文档。

通过“过滤”查询,ES可能会优化此计算,例如首先执行过滤器,然后对有限的文档集执行查询,节省测试与查询不匹配的文档的时间,以及如果它们与查询匹配则计算得分。

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

您还可以显式控制“已过滤”查询的执行(请参阅文档),以针对您的特定用例对其进行优化。

答案 1 :(得分:9)

两种类型的过滤器也可称为前置和后置过滤器。正如@alexey所解释的那样,在查询之后执行根级别过滤器,并在查询之前执行过滤查询中的过滤。

此外,您需要了解相同的其他影响,然后执行它们的顺序。过滤器"过滤"查询来自查询范围,这意味着在计算聚合时,将考虑过滤后的输出,而在根级别过滤器聚合的情况下,将仅对不包括过滤器的查询结果执行。虽然在这两种情况下结果文件都是相同的。

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