ES的分组聚合

类似于select brandId, sum(salesVolume) from live_room group by brandId ;
求每个品牌下的直播间销额有多少

正文开始

新建索引live_room

mapping结构如下
背景:直播间id关联的品牌销售情况,每个直播间都能带很多商品,自然的,每个直播间也能通过商品关联到很多品牌。计算每个品牌的销额销量等数据,就是此直播间这个品牌关联商品的和
注意: 如果需要使用分组完之后的聚合功能,需要把一些list的字段类型设为nested!

PUT live_room
PUT live_room/_mapping
{"properties": {"roomId": {"type": "long"},"roomName": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"brandDataNested": {"type": "nested","properties": {"id": {"type": "long"},"liveSales": {"type": "long"},"name": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"productNum": {"type": "long"},"salesVolume": {"type": "long"},"sort": {"type": "long"}}}}
}

数据情况

塞两条数据

PUT live_room/_doc/3512897908123112
{"roomId": 3512897908123112,"roomName": "大促饮品专场","brandDataNested": [{"liveSales": 6211,"name": "伊*","salesVolume": 1491562300,"id": 9321,"productNum": 32,"sort": 1},{"liveSales": 8,"name": "蒙*","salesVolume": 89800,"id": 1419,"productNum": 3,"sort": 2}]
}PUT live_room/_doc/3512897908123115
{"roomId": 3512897908123115,"roomName": "大促活动卖饮品啦!!","brandDataNested": [{"liveSales": 5800,"name": "伊*","salesVolume": 1342332400,"id": 9321,"productNum": 10,"sort": 1},{"liveSales": 780,"name": "元气*","salesVolume": 12988900,"id": 8965,"productNum": 9,"sort": 2}]
}

使用Agg聚合数据

GET live_room/_search
{"size": 0,"aggregations": {"brandDataNested": {"nested": {"path": "brandDataNested"},"aggregations": {"brandSalesVolumeMax": {"terms": {"field": "brandDataNested.name.keyword","size": 10,"order": [{"brandSalesVolumeMax": "desc"},{"_key": "asc"}]},"aggregations": {"brandSalesVolumeMax": {"sum": {"field": "brandDataNested.salesVolume"}}}}}}}
}

这里实现了按品牌名分组聚合统计,并且计算了每个品牌的销额sum

Java代码实现

        //第一组聚合,按brandDataNested的name分组//这个size是一个可配置的精度TermsAggregationBuilder brandNameAgg = AggregationBuilders.terms("brand").field("brandDataNested.name.keyword").size(10);//第二组聚合,按name分组之后再使用sum求销额的和String sumName = "brandSalesVolume";SumAggregationBuilder brandSalesVolume = AggregationBuilders.sum(sumName).field("brandDataNested.salesVolume");//第一组聚合中提交第二组聚合brandNameAgg.subAggregation(brandSalesVolume);//聚合排序,这里使用销额倒排brandNameAgg.order(BucketOrder.aggregation(sumName, false));//在最外层的查询将agg聚合设置进去,并且使用nestedNestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("brandDataNested", "brandDataNested").subAggregation(brandNameAgg);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//此处可以添加筛选语句
//        searchSourceBuilder.query(query);//聚合查询searchSourceBuilder.aggregation(nestedAggregationBuilder);//只返回聚合统计结果,不返回关联的具体文档searchSourceBuilder.size(0);SearchRequest request = new SearchRequest("live_room");request.source(searchSourceBuilder);try {SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);//获取所有桶Aggregations brandNameAggregations = search.getAggregations();ParsedNested brandDataNested = brandNameAggregations.get("brandDataNested");Aggregations brandDataNestedAggregations = brandDataNested.getAggregations();Terms brandNameTerms = brandDataNestedAggregations.get("brand");for (Terms.Bucket brandNameTermsBucket : brandNameTerms.getBuckets()) {Aggregations aggregationsSon = brandNameTermsBucket.getAggregations();String keyAsString = brandNameTermsBucket.getKeyAsString();long docCount = brandNameTermsBucket.getDocCount();ParsedSum brandSalesVolumeMax1 = aggregationsSon.get(sumName);double value = brandSalesVolumeMax1.getValue();}} catch (Exception e) {log.error("es查找报错,{}: {}", EsIndexEnum.DCM_LIVE_SEARCH_FOR_FIND.getIndex(), e.getMessage(), e);}

代码中的size 10需要依据自己业务进行配置,es官网文档中的解释是:

示例会确保当字段唯一值在 100 以内时会得到非常准确的结果。尽管算法是无法保证这点的,但如果基数在阈值以下,几乎总是 100% 正确的。高于阈值的基数会开始节省内存而牺牲准确度,同时也会对度量结果带入误差。

还有一点,如果说,你需要聚合非常多的数据,在此文档的例子中的话,就是直播间数量巨大,需要聚合计算的品牌也众多,你可能需要提前计算好hash值,官网文档中的解释是:

现在 cardinality 度量会读取 “color.hash” 里的值(预先计算的哈希值),取代动态计算原始值的哈希。
单个文档节省的时间是非常少的,但是如果你聚合一亿数据,每个字段多花费 10 纳秒的时间,那么在每次查询时都会额外增加 1 秒,如果我们要在非常大量的数据里面使用 cardinality ,我们可以权衡使用预计算的意义,是否需要提前计算 hash,从而在查询时获得更好的性能,做一些性能测试来检验预计算哈希是否适用于你的应用场景。。

debug调试结果:

这里还有一个小技巧,在调试的时候,最后发起请求的request中,直接点击source,会拼接好es的dsl语句,可以直接复制在es的kibana控制台使用

ES分组聚合Agg nested相关推荐

  1. es 聚合查询 java api_javaAPI操作ES分组聚合

    连接es的客户端使用的 TransportClient SearchRequestBuilder requestBuilder = transportClient.prepareSearch(indi ...

  2. ES分组聚合:计算每个tag下的商品数量且某个filed包含指定关键字,分组,平均,每个tags下的平均价格,排序,指定范围区间

    1.第一个分析需求:计算每个tag下的商品数量 GET /ecommerce/product/_search {"aggs": {"group_by_tags" ...

  3. python pandas聚合_Python Pandas分组聚合的实现方法

    Pycharm 鼠标移动到函数上,CTRL+Q可以快速查看文档,CTR+P可以看基本的参数. apply(),applymap()和map() apply()和applymap()是DataFrame ...

  4. Python数据清洗小技巧——分组聚合

    分组聚合 分组 groupby原理 import numpy as np import pandas as pddf = pd.DataFrame(data = {'sex':np.random.ra ...

  5. pandas使用groupby函数进行分组聚合、使用agg函数指定聚合统计计算的数值变量、并自定义统计计算结果的名称(naming columns after aggregation)

    pandas使用groupby函数进行分组聚合.使用agg函数指定聚合统计计算的数值变量.并自定义统计计算结果的名称(naming columns after aggregation in dataf ...

  6. pandas使用groupby函数进行分组聚合并使用agg函数将每个分组特定变量对应的多个内容组合到一起输出(merging content within a specific column of g

    pandas使用groupby函数进行分组聚合并使用agg函数将每个分组特定变量对应的多个内容组合到一起输出(merging content within a specific column of g ...

  7. pandas使用groupby函数按照多个分组变量进行分组聚合统计、使用agg函数计算分组的多个统计指标(grouping by multiple columns in dataframe)

    pandas使用groupby函数按照多个分组变量进行分组聚合统计.使用agg函数计算分组的多个统计指标(grouping by multiple columns in dataframe) 目录

  8. pandas使用groupby函数、agg函数获取每个分组聚合对应的标准差(std)实战:计算分组聚合单数据列的标准差(std)、计算分组聚合多数据列的标准差(std)

    pandas使用groupby函数.agg函数获取每个分组聚合对应的标准差(std)实战:计算分组聚合单数据列的标准差(std).计算分组聚合多数据列的标准差(std) 目录

  9. pandas使用groupby函数、agg函数获取每个分组聚合对应的均值(mean)实战:计算分组聚合单数据列的均值、计算分组聚合多数据列的均值

    pandas使用groupby函数.agg函数获取每个分组聚合对应的均值(mean)实战:计算分组聚合单数据列的均值.计算分组聚合多数据列的均值 目录

  10. python和R对dataframe的分组聚合操作:dplyr、groupby、agg、group_by、nunique、reset_index、rename、summarise、n_distinct

    python和R对dataframe的分组聚合操作:dplyr.groupby.agg.group_by.nunique.reset_index.rename.summarise.n_distinct ...

最新文章

  1. 腾讯AI Lab两大算法刷新人脸识别与检测纪录,秉承「基础研究+落地应用」之路
  2. python cnn图像分类_关于CNN图像分类的一份综合设计指南
  3. 信息安全系统设计基础第二周学习总结
  4. ros发布节点信息python_vscode开发ROS1(13)-python实现话题通信(msg)
  5. 浅析MSIL中间语言——基础篇
  6. Java 常用对象-StringBuffer类
  7. K8S_Google工作笔记0012---通过二进制方式_部署master组件
  8. VS2017产品密钥
  9. python实现算法改进_运动目标检测vibe算法及其改进Python实现
  10. 安卓原生镜像(中国网站)
  11. qt调用vc编写库文件的方法
  12. python制作APP,此APP可识别TEM图片结构轮廓,并将坐标提取到excel中,画出TEM结构轮廓图(tkinter,opencv-python)
  13. oracle数据泵PARALLEL,EXPDP的parallel参数
  14. mybatis之choose标签
  15. 《设计模式之禅》笔记
  16. Business English-Unit 4 Memos -B
  17. Mapbox Android学习笔记(8)离线地图
  18. Flume拦截器实战案例
  19. C++第3次实验:【项目三】定期存款利息计算器
  20. YOLO与voc格式互转,超详细

热门文章

  1. 根据旋转矩阵计算角度差
  2. ARMv8基础架构之内存屏障(Memory Barriers)
  3. php session fixation,什么是session fixation攻击
  4. 天地三才阵——【Java三大特征】
  5. 浅谈几个倾斜摄影三维模型的修补软件
  6. 山东省农商行计算机真题,2018山东农商行招聘考试题库:计算机试题三
  7. Openjudge1.5答案
  8. 【论文】论文阅读记录
  9. 树莓派 pcf8591 AD转换模块使用
  10. 深度学习-胶囊网络学习