“先过滤再汇总”还是“过滤汇总”?

时间:2019-08-27 02:52:19

标签: elasticsearch elasticsearch-aggregation

我最近正在研究ES,发现可以达到几乎相同的结果,但是对于差异我没有 clear 的想法在这两个之间。

"Filter then Aggregation"

echo Remember to call vcvarsall.bat to complete environment setup!

"Filter Aggregation"

POST kibana_sample_data_flights/_search
{
  "size": 0,
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "DestCountry": "CA"
        }
      }
    }
  },
  "aggs": {
    "ca_weathers": {
      "terms": { "field": "DestWeather" }
    }
  }
}

我的问题

  1. 为什么有两个相似的功能?我相信我错了,但是有什么区别呢? (请忽略结果格式,这不是我要问的问题; p)
  2. 如果我想过滤掉不相关/不匹配并开始对许多文档进行汇总的哪个更好?

3 个答案:

答案 0 :(得分:1)

"query"中使用它时,将在索引中的所有文档上创建一个上下文。在这种情况下,它的作用类似于普通的过滤器,例如:SELECT * FROM index WHERE (my_filter_condition1 AND my_filter_condition2 OR my_filter_condition3...)

"aggs"中使用它时,您正在所有先前可能已经(或尚未)过滤的文档上创建上下文。假设您的结构如下:

#OPTION A
{
    "aggs":{
        t_shirts" : {
            "filter" : { "term": { "type": "t-shirt" } }
        }
    }
}

没有“查询”,与拥有

完全相同
#OPTION B
{
    "query":{
        "filter" : { "term": { "type": "t-shirt" } }
    }
}

但是结果将在不同的字段中返回。

在选项A中,结果将在aggregations字段中返回。

在选项B中,结果将在hits字段中返回。

我建议您始终在query部分应用过滤器,这样您就可以处理已过滤文档的次安全聚合。同样是因为集成成本比查询更高的性能

希望这会有所帮助! :D

答案 1 :(得分:1)

隔离使用的两个过滤器都是等效的。如果您未加载任何结果(匹配数),则没有任何区别。但是您可以将列表和聚合结合起来。您可以查询或过滤要列出的文档,并在受aggs过滤器进一步限制的存储桶上计算聚合。像这样:

POST kibana_sample_data_flights/_search
{
  "size": 100,
  "query": {
    "bool": {
      "filter": {
        "term": {
          ... some other filter
        }
      }
    }
  },
  "aggs": {
    "ca_filter": {
      "term": {
         "TestCountry": "CA"
      }
    },
    "aggs": {
      "ca_weathers": {
        "terms": { "field": "DestWeather" }
      }
    }
  }
}

但是您更有可能需要其他方式,即。在显示来自特定查询的文档时,对所有文档进行汇总,以显示摘要信息。在这种情况下,您需要将聚集与post_filter结合使用。

答案 2 :(得分:0)

@Val的评论,我可能在这里引用以供参考:

  

在选项A中,汇总将在所有文档上运行。在选项B中,文档首先被过滤,汇总将仅在所选文档上运行。假设您有1000万个文档,而过滤器仅选择了100个,那么很明显,选项B总是会更快。