【发布时间】:2021-12-06 14:40:48
【问题描述】:
使用 Elasticsearch 的 _search API 时,如果您将 size 设置为 10,并执行 avg 指标聚合,则平均值将是整个数据集中与查询匹配的所有值,而不仅仅是 10 个的平均值hits 数组中返回的项目。
另一方面,如果您执行 terms 聚合并将 terms 聚合的 size 设置为 10,则对这些 terms 存储桶执行 avg_buckets 聚合将计算超过只有这 10 个桶 - 不是所有潜在的桶。
如何计算所有潜在存储桶中某个字段的平均值,但 buckets 数组中仍然只有 10 个项目?
为了使我的问题更具体,请考虑以下示例:假设我是一名帽子制造商。多家商店携带我的帽子。我有一个 Elasticsearch 索引 hat-sales,每次售出我的一顶帽子时,它都有一个文档。本文档中包含价格和出售帽子的商店。
以下是我测试过的文档的两个示例:
{
"type": "top",
"color": "black",
"price": 19,
"store": "Macy's"
}
{
"type": "fez",
"color": "red",
"price": 94,
"store": "Walmart"
}
如果我想找到我售出的所有帽子的平均价格,我可以运行这个:
GET hat-sales/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"average_hat_price": {
"avg": {
"field": "price"
}
}
}
}
无论 size 设置为 0、3 还是其他任何值,average_hat_price 都是相同的。
好的,现在我想找出销售帽子数量最多的前 3 家商店。我还想将它们与商店出售的平均帽子数量进行比较。所以我想要做这样的事情:
GET hat-sales/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"by_store": {
"terms": {
"field": "store.keyword",
"size": 3
},
"aggs": {
"sales_count": {
"cardinality": {
"field": "_id"
}
}
}
},
"avg sales at a store": {
"avg_bucket": {
"buckets_path": "by_store>sales_count"
}
}
}
}
产生的响应
"aggregations" : {
"by_store" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 8,
"buckets" : [
{
"key" : "Macy's",
"doc_count" : 6,
"sales_count" : {
"value" : 6
}
},
{
"key" : "Walmart",
"doc_count" : 5,
"sales_count" : {
"value" : 5
}
},
{
"key" : "Dillard's",
"doc_count" : 3,
"sales_count" : {
"value" : 3
}
}
]
},
"avg sales at a store" : {
"value" : 4.666666666666667
}
}
问题在于 avg sales at a store 仅针对 Macy's、Walmart 和 Dillard's 进行计算。如果我想找到所有商店的平均值,我必须将 aggs.by_store.terms.size 设置为 65536。(65536 因为这是默认的最大术语桶数,我不知道先验有多少桶可能有。)这给出了以下结果:
"aggregations" : {
"by_store" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "Macy's",
"doc_count" : 6,
"sales_count" : {
"value" : 6
}
},
{
"key" : "Walmart",
"doc_count" : 5,
"sales_count" : {
"value" : 5
}
},
{
"key" : "Dillard's",
"doc_count" : 3,
"sales_count" : {
"value" : 3
}
},
{
"key" : "Target",
"doc_count" : 3,
"sales_count" : {
"value" : 3
}
},
{
"key" : "Harrod's",
"doc_count" : 2,
"sales_count" : {
"value" : 2
}
},
{
"key" : "Men's Warehouse",
"doc_count" : 2,
"sales_count" : {
"value" : 2
}
},
{
"key" : "Sears",
"doc_count" : 1,
"sales_count" : {
"value" : 1
}
}
]
},
"avg sales at a store" : {
"value" : 3.142857142857143
}
}
因此,每家商店平均售出的帽子数量是 3.1 顶,而不是 4.6 顶。但在 buckets 数组中,我只想查看前 3 家商店。
【问题讨论】:
-
你能分享你正在运行的查询吗?
-
先生。 Walkom,我已经分享了疑问。我试图使示例尽可能简单,同时仍然显示我的问题。
标签: elasticsearch elasticsearch-aggregation