如何在不返回 Elasticsearch 中的所有存储桶的情况下执行管道聚合
How to perform a pipeline aggregation without returning all buckets in Elasticsearch
我正在使用 Elasticsearch 2.3,我正在尝试使用管道聚合执行两步计算。
我只对管道聚合的最终结果感兴趣,但 Elasticsearch return 包含所有存储桶信息。
因为我有大量的桶(数千万或数亿),这是令人望而却步的。不幸的是,我找不到告诉 Es 不要 return 所有这些信息的方法。
这是一个玩具示例。我有一个文档类型 obj
的索引 test-index
。 obj
有两个字段,key
和 values
。
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 100,
"key": "foo"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 20,
"key": "foo"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 50,
"key": "bar"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 60,
"key": "bar"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 70,
"key": "bar"
}'
我想获得具有相同 key
s 的 obj
s 中最小值 value
的平均值(在所有 key
s 中)。
最小值的平均值。
Elasticsearch 允许我这样做:
curl -XPOST 'http://10.10.0.7:9200/test-index/obj/_search' -d '{
"size": 0,
"query": {
"match_all": {}
},
"aggregations": {
"key_aggregates": {
"terms": {
"field": "key",
"size": 0
},
"aggs": {
"min_value": {
"min": {
"field": "value"
}
}
}
},
"avg_min_value": {
"avg_bucket": {
"buckets_path": "key_aggregates>min_value"
}
}
}
}'
但是这个查询 return 是每个桶的最小值,虽然我不需要它:
{
"took": 21,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 0,
"hits": [
]
},
"aggregations": {
"key_aggregates": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "bar",
"doc_count": 2,
"min_value": {
"value": 50
}
},
{
"key": "foo",
"doc_count": 2,
"min_value": {
"value": 20
}
}
]
},
"avg_min_value": {
"value": 35
}
}
}
有没有办法去掉"buckets": [...]
里面的所有信息?我只对 avg_min_value
.
感兴趣
在这个玩具示例中,这似乎不是问题,但是当不同 key
的数量不大(数千万或数亿)时,查询响应非常大,我会喜欢修剪它。
有没有办法用 Elasticsearch 做到这一点?还是我的数据建模有误?
注意:按键预先聚合我的数据是不可接受的,因为我查询的 match_all
部分可能会被复杂且未知的过滤器替换。
NB2:在我的 terms
聚合中将 size
更改为非负数是不可接受的,因为它会改变结果。
我遇到了同样的问题,经过大量研究后我找到了解决方案,我想在这里分享一下。
您可以使用 Response Filtering 功能来过滤您想要接收的答案部分。
您应该可以通过将查询参数 filter_path=aggregations.avg_min_value
添加到搜索 URL 来实现您想要的结果。在示例中,它看起来应该类似于:
curl -XPOST 'http://10.10.0.7:9200/test-index/obj/_search?filter_path=aggregations.avg_min_value' -d '{
"size": 0,
"query": {
"match_all": {}
},
"aggregations": {
"key_aggregates": {
"terms": {
"field": "key",
"size": 0
},
"aggs": {
"min_value": {
"min": {
"field": "value"
}
}
}
},
"avg_min_value": {
"avg_bucket": {
"buckets_path": "key_aggregates>min_value"
}
}
}
}'
PS:如果您找到其他解决方案,您介意在这里分享吗?谢谢!
我正在使用 Elasticsearch 2.3,我正在尝试使用管道聚合执行两步计算。 我只对管道聚合的最终结果感兴趣,但 Elasticsearch return 包含所有存储桶信息。
因为我有大量的桶(数千万或数亿),这是令人望而却步的。不幸的是,我找不到告诉 Es 不要 return 所有这些信息的方法。
这是一个玩具示例。我有一个文档类型 obj
的索引 test-index
。 obj
有两个字段,key
和 values
。
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 100,
"key": "foo"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 20,
"key": "foo"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 50,
"key": "bar"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 60,
"key": "bar"
}'
curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
"value": 70,
"key": "bar"
}'
我想获得具有相同 key
s 的 obj
s 中最小值 value
的平均值(在所有 key
s 中)。
最小值的平均值。
Elasticsearch 允许我这样做:
curl -XPOST 'http://10.10.0.7:9200/test-index/obj/_search' -d '{
"size": 0,
"query": {
"match_all": {}
},
"aggregations": {
"key_aggregates": {
"terms": {
"field": "key",
"size": 0
},
"aggs": {
"min_value": {
"min": {
"field": "value"
}
}
}
},
"avg_min_value": {
"avg_bucket": {
"buckets_path": "key_aggregates>min_value"
}
}
}
}'
但是这个查询 return 是每个桶的最小值,虽然我不需要它:
{
"took": 21,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 0,
"hits": [
]
},
"aggregations": {
"key_aggregates": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "bar",
"doc_count": 2,
"min_value": {
"value": 50
}
},
{
"key": "foo",
"doc_count": 2,
"min_value": {
"value": 20
}
}
]
},
"avg_min_value": {
"value": 35
}
}
}
有没有办法去掉"buckets": [...]
里面的所有信息?我只对 avg_min_value
.
在这个玩具示例中,这似乎不是问题,但是当不同 key
的数量不大(数千万或数亿)时,查询响应非常大,我会喜欢修剪它。
有没有办法用 Elasticsearch 做到这一点?还是我的数据建模有误?
注意:按键预先聚合我的数据是不可接受的,因为我查询的 match_all
部分可能会被复杂且未知的过滤器替换。
NB2:在我的 terms
聚合中将 size
更改为非负数是不可接受的,因为它会改变结果。
我遇到了同样的问题,经过大量研究后我找到了解决方案,我想在这里分享一下。
您可以使用 Response Filtering 功能来过滤您想要接收的答案部分。
您应该可以通过将查询参数 filter_path=aggregations.avg_min_value
添加到搜索 URL 来实现您想要的结果。在示例中,它看起来应该类似于:
curl -XPOST 'http://10.10.0.7:9200/test-index/obj/_search?filter_path=aggregations.avg_min_value' -d '{
"size": 0,
"query": {
"match_all": {}
},
"aggregations": {
"key_aggregates": {
"terms": {
"field": "key",
"size": 0
},
"aggs": {
"min_value": {
"min": {
"field": "value"
}
}
}
},
"avg_min_value": {
"avg_bucket": {
"buckets_path": "key_aggregates>min_value"
}
}
}
}'
PS:如果您找到其他解决方案,您介意在这里分享吗?谢谢!