{
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "order_date",
"calendar_interval": "month"
},
"aggs": {
"total_sales": {
"sum": {
"field": "sales"
}
},
"tshirt_sales_sum": {
"sum": {
"field": "tshirt_sales"
}
},
"tshirt_sales_percentage": {
"bucket_script": {
"buckets_path": {
"total": "total_sales",
"tshirt": "tshirt_sales_sum"
},
"script": "params.total > 0 ? (params.tshirt / params.total * 100) : 0"
}
}
}
}
}
}
为什么bucket_path不写成sales_per_month>total_sales?
在 Elasticsearch 的管道聚合中,`buckets_path`的路径解析方式取决于聚合的结构和层次关系。让我们详细分析为什么在某些情况下需要显式指定路径,而在其他情况下可以省略部分路径。
1.路径解析的规则
`buckets_path`的路径解析遵循以下规则:
• 相对路径:`buckets_path`是相对于当前管道聚合的位置来解析的。它不是绝对路径,而是从当前聚合的上下文中查找目标聚合。
• 层级关系:如果目标聚合是嵌套在当前聚合的父聚合中,需要使用`>`符号来表示层级关系。
• 同级关系:如果目标聚合与当前聚合处于同一层级(即兄弟聚合),则不需要显式指定父聚合的路径。
2.示例分析
在你的查询中:
```json
{
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "order_date",
"calendar_interval": "month"
},
"aggs": {
"total_sales": {
"sum": {
"field": "sales"
}
},
"tshirt_sales_sum": {
"sum": {
"field": "tshirt_sales"
}
},
"tshirt_sales_percentage": {
"bucket_script": {
"buckets_path": {
"total": "total_sales",
"tshirt": "tshirt_sales_sum"
},
"script": "params.total > 0 ? (params.tshirt / params.total * 100) : 0"
}
}
}
}
}
}
```
为什么`buckets_path`不写成`sales_per_month>total_sales`?
1. 相对路径的解析:
• 在`tshirt_sales_percentage`的`bucket_script`中,`buckets_path`是相对于当前聚合(`tshirt_sales_percentage`)的上下文来解析的。
• `total_sales`和`tshirt_sales_sum`与`tshirt_sales_percentage`处于同一层级(都是`sales_per_month`的子聚合),因此可以直接引用它们的名称,而不需要显式指定父聚合的路径。
2. 层级关系的省略:
• 如果目标聚合与当前聚合处于同一层级,Elasticsearch 会自动解析路径,而不需要显式指定父聚合的路径。
• 如果目标聚合是嵌套在更深层次的聚合中,才需要使用`>`符号来表示层级关系。
3.显式路径的使用场景
如果目标聚合是嵌套在更深层次的聚合中,需要显式指定路径。例如:
```json
{
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "order_date",
"calendar_interval": "month"
},
"aggs": {
"product_sales": {
"terms": {
"field": "product"
},
"aggs": {
"total_sales": {
"sum": {
"field": "sales"
}
}
}
},
"tshirt_sales_percentage": {
"bucket_script": {
"buckets_path": {
"total": "product_sales>total_sales"
},
"script": "params.total"
}
}
}
}
}
}
```
在这个例子中:
• `product_sales`是一个嵌套在`sales_per_month`内的聚合。
• `total_sales`是嵌套在`product_sales`内的聚合。
• 在`tshirt_sales_percentage`的`buckets_path`中,需要显式指定路径`product_sales>total_sales`,因为`total_sales`不在当前聚合的同一层级。
4.总结
• 同级聚合:如果目标聚合与当前聚合处于同一层级,可以直接引用聚合名称,而不需要显式指定父聚合的路径。
• 嵌套聚合:如果目标聚合是嵌套在更深层次的聚合中,需要使用`>`符号来表示层级关系。
在你的原始查询中,`total_sales`和`tshirt_sales_sum`与`tshirt_sales_percentage`处于同一层级,因此可以直接引用它们的名称,而不需要写成`sales_per_month>total_sales`。