"Filter then Aggregation" 还是只是 "Filter Aggregation"?
"Filter then Aggregation" or just "Filter Aggregation"?
我最近在研究 ES,我发现我可以达到 几乎 相同的结果,但我没有 清楚 的想法这两者之间的差异。
POST kibana_sample_data_flights/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {
"term": {
"DestCountry": "CA"
}
}
}
},
"aggs": {
"ca_weathers": {
"terms": { "field": "DestWeather" }
}
}
}
POST kibana_sample_data_flights/_search
{
"size": 0,
"aggs": {
"ca": {
"filter": {
"term": {
"DestCountry": "CA"
}
},
"aggs": {
"_weathers": {
"terms": { "field": "DestWeather" }
}
}
}
}
}
我的问题
- 为什么有两个相似的函数?我相信我错了,但那有什么区别呢?
(请忽略结果格式,这不是我要问的问题;p)
- 如果我想过滤掉 unrelated/unmatched 并开始对大量文档进行聚合,哪个更好?
当您在 "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" } }
}
}
}
没有 "query" 与有
完全一样
#OPTION B
{
"query":{
"filter" : { "term": { "type": "t-shirt" } }
}
}
但是结果将在不同的字段中返回。
在选项A中,结果将在aggregations
字段中返回。
在选项B中,结果将在hits
字段中返回。
我建议始终在 query
部分应用过滤器,这样您就可以处理已过滤文档的后续聚合。还因为 聚合比查询花费更多的性能。
希望对您有所帮助! :D
两个单独使用的过滤器是等效的。如果您没有加载任何结果(点击),则没有区别。但是您可以组合列表和聚合。您可以查询或过滤您的文档以进行列表,并计算进一步受 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.
结合使用
来自@Val评论的回答,我只引用这里供参考:
In option A, the aggregation will be run on ALL documents. In option B, the documents are first filtered and the aggregation will be run only on the selected documents. Say you have 10M documents and the filter select only a 100, it's pretty evident that option B will always be faster.
我最近在研究 ES,我发现我可以达到 几乎 相同的结果,但我没有 清楚 的想法这两者之间的差异。
POST kibana_sample_data_flights/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {
"term": {
"DestCountry": "CA"
}
}
}
},
"aggs": {
"ca_weathers": {
"terms": { "field": "DestWeather" }
}
}
}
POST kibana_sample_data_flights/_search
{
"size": 0,
"aggs": {
"ca": {
"filter": {
"term": {
"DestCountry": "CA"
}
},
"aggs": {
"_weathers": {
"terms": { "field": "DestWeather" }
}
}
}
}
}
我的问题
- 为什么有两个相似的函数?我相信我错了,但那有什么区别呢? (请忽略结果格式,这不是我要问的问题;p)
- 如果我想过滤掉 unrelated/unmatched 并开始对大量文档进行聚合,哪个更好?
当您在 "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" } }
}
}
}
没有 "query" 与有
完全一样#OPTION B
{
"query":{
"filter" : { "term": { "type": "t-shirt" } }
}
}
但是结果将在不同的字段中返回。
在选项A中,结果将在aggregations
字段中返回。
在选项B中,结果将在hits
字段中返回。
我建议始终在 query
部分应用过滤器,这样您就可以处理已过滤文档的后续聚合。还因为 聚合比查询花费更多的性能。
希望对您有所帮助! :D
两个单独使用的过滤器是等效的。如果您没有加载任何结果(点击),则没有区别。但是您可以组合列表和聚合。您可以查询或过滤您的文档以进行列表,并计算进一步受 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.
结合使用来自@Val评论的回答,我只引用这里供参考:
In option A, the aggregation will be run on ALL documents. In option B, the documents are first filtered and the aggregation will be run only on the selected documents. Say you have 10M documents and the filter select only a 100, it's pretty evident that option B will always be faster.