在ES搜索中,聚合是一个非常重要的概念。通过ES聚合,我们可以快速地对搜索结果进行汇总统计,方便查询分析。而在实际应用中,有时候需要对多个字段进行聚合,这时就需要使用到ES的多字段聚合。
一、使用多字段聚合进行分组统计
使用ES的多字段聚合进行分组统计是一个非常常见的需求。比如,在一个电商网站中,需要对商品进行分组统计,统计出每个品牌下每个分类的销售数量以及销售额。这时就需要使用到ES的多字段聚合。
{ "aggs": { "brand_group": { "terms": { "field": "brand.keyword", "size": 10 }, "aggs": { "category_group": { "terms": { "field": "category.keyword", "size": 10 }, "aggs": { "sales_count": { "sum": { "field": "sales_count" } }, "sales_sum_amount": { "sum": { "field": "sales_amount" } } } } } } } }
上面的代码中,首先使用了一个名为“brand_group”的聚合,根据“brand.keyword”字段进行聚合,并限制聚合结果返回的桶的数量为10个。在“brand_group”聚合下嵌套了一个名为“category_group”的聚合,根据“category.keyword”字段进行聚合,并同样限制返回的桶数量为10个。
在“category_group”聚合下,有两个子聚合“sales_count”和“sales_sum_amount”。这两个子聚合分别聚合了“sales_count”和“sales_amount”字段,并对这两个字段进行求和。这样就能统计出每个品牌下每个分类的销售数量以及销售额。
二、使用多字段聚合进行统计排序
除了进行分组统计,还可以使用ES的多字段聚合进行统计排序。比如,在一个房产网站中,需要对房源进行统计排序,以便用户更快地找到自己需要的房源。这时就可以使用ES的多字段聚合进行统计排序。
{ "size": 10, "aggs": { "price_stat": { "stats": { "field": "price" } }, "price_group": { "histogram": { "field": "price", "interval": 500 }, "aggs": { "area_group": { "terms": { "field": "area" }, "aggs": { "price_avg": { "avg": { "field": "price" } } } } } }, "price_ranges": { "range": { "field": "price", "ranges": [ { "from": 0, "to": 500 }, { "from": 500, "to": 1000 }, { "from": 1000, "to": 2000 }, { "from": 2000, "to": 5000 } ] } } } }
上面的代码中,首先使用了一个“stats”聚合,对“price”字段进行统计,得到该字段的最大值、最小值、平均值和总和。
在“price_group”聚合中,使用了一个“histogram”聚合对“price”字段进行切分,并在每个价位桶中再使用“terms”聚合按照“area”字段进行聚合。最终在每个桶下面还使用了一个“avg”聚合,对“price”字段求出了该桶内的平均价格。
最后一个聚合“price_ranges”使用了一个“range”聚合,将价格按照一定的区间进行归纳,并使用“from”和“to”字段指定了价格区间的范围。这样就可以方便地进行价格筛选,供用户使用。
三、使用多字段聚合进行数据透视
除了分组统计和统计排序,ES的多字段聚合还可以进行数据透视。比如,在一个企业的订单管理系统中,需要统计某个时间段内每个员工的销售额,并按照部门进行分类,同时还需要统计每个员工的销售额占该部门总销售额的百分比。
{ "aggs": { "dept_group": { "terms": { "field": "dept.keyword", "size": 10 }, "aggs": { "employee_group": { "terms": { "field": "employee.keyword", "size": 10 }, "aggs": { "sales_amount": { "sum": { "field": "sales_amount" } }, "dept_sales_amount": { "sum": { "field": "sales_amount" }, "partition": { "terms": { "field": "dept.keyword", "size": 10 } } } } } } } } }
上面的代码中,首先使用了一个名为“dept_group”的聚合,根据“dept.keyword”字段进行聚合,并限制结果桶的数量为10个。在“dept_group”聚合下面嵌套了一个名为“employee_group”的聚合,根据“employee.keyword”字段进行聚合,并同样限制结果桶数量为10个。
在“employee_group”聚合下,有两个子聚合“sales_amount”和“dept_sales_amount”。其中,“sales_amount”聚合对“sales_amount”字段进行求和,统计每个员工的销售额;“dept_sales_amount”聚合也对“sales_amount”字段进行求和,并增加了“partition”子聚合,对“dept.keyword”进行聚合,计算出每个部门的总销售额。
通过这两个聚合的组合,我们可以计算出每个员工的销售额,以及他所在部门的总销售额。这样就可以方便地计算每个员工的销售额占该部门总销售额的百分比。