一、介绍 (偏自我理解)
1.ES聚合查询通用流程
1.分组 ( 好比Mysql ---> group by )
2.组内聚合 也叫 组内指标( 好比Mysql ---> SUM()、COUNT()、AVG()、MAX()、MIN() )
2.桶(我要是es开发者,我起名叫啥都行)
1.满足特定条件的文档的集合,叫做桶。
桶的就是一组数据的集合,对数据分组后,得到一组组的数据,就是一个个的桶
提示:桶等同于组,分桶和分组是一个意思,ES使用桶代表一组相同特征的数据。
3.指标
1.指标指的是对文档进行统计计算方式,又叫指标聚合。
2.强大之处就是,前面将数据经过一轮桶聚合,把数据分成一个个的桶之后,我们根据上面计算指标对桶内的数据进行统计。
{
"aggregations" : {
"<aggregation_name>" : {
"<aggregation_type>" : {
<aggregation_body>
}
[,"aggregations" : { [<sub_aggregation>]+ } ]? // 嵌套聚合查询,支持多层嵌套
}
[,"<aggregation_name_2>" : { ... } ]* // 多个聚合查询,每个聚合查询取不同的名字
}
}
说明:
1)aggregations - 代表聚合查询语句,可以简写为aggs
2)<aggregation_name> - 代表一个聚合计算的名字,可以随意命名,因为ES支持一次进行多次统计分析查询,后面需要通过这个名字在查询结果中找到我们想要的计算结果。
3)<aggregation_type> - 聚合类型,代表我们想要怎么统计数据,主要有两大类聚合类型,桶聚合和指标聚合,这两类聚合又包括多种聚合类型,例如:指标聚合:sum、avg, 桶聚合:terms、Date histogram等等。
4)<aggregation_body> - 聚合类型的参数,选择不同的聚合类型,有不同的参数。
5)aggregation_name_2 - 代表其他聚合计算的名字,意思就是可以一次进行多种类型的统计。
————————————————
版权声明:本文为CSDN博主「书虫罢了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lazyboy2/article/details/125122815
4.举例说明
下面看个简单的聚合查询的例子:
假设存在一个order索引,存储了每一笔汽车销售订单,里面包含了汽车颜色字段color.
GET /order/_search
{
"size" : 0, // 设置size=0的意思就是,仅返回聚合查询结果,不返回普通query查询结果。
"aggs" : { // 聚合查询语句的简写
"popular_colors" : { // 给聚合查询取个名字,叫popular_colors
"terms" : { // 聚合类型为,terms,terms是桶聚合的一种,类似SQL的group by的作用,根据字段分组,相同字段值的文档分为一组。
"field" : "color" // terms聚合类型的参数,这里需要设置分组的字段为color,根据color分组
}
}
}
}
上面使用了terms桶聚合,而且没有明确指定指标聚合函数,默认使用的是Value Count聚合指标统计文档总数, 整个统计的意思是统计每一种汽车颜色的销量。
{
...
"hits": { // 因为size=0,所以query查询结果为空
"hits": []
},
"aggregations": { // 聚合查询结果
"popular_colors": { // 这个就是popular_colors聚合查询的结果,这就是为什么需要给聚合查询取个名字的原因,如果有多个聚合查询,可以通过名字查找结果
"buckets": [ // 因为是桶聚合,所以看到返回一个buckets数组,代表分组的统计情况,下面可以看到每一种颜色的销量情况
{
"key": "red",
"doc_count": 4 // 红色的汽车销量为4
},
{
"key": "blue",
"doc_count": 2
},
{
"key": "green",
"doc_count": 2
}
]
}
}
}
5.常用方法
常用的统计函数如下:
- Value Count - 类似sql的count函数,统计总数
- Cardinality - 类似SQL的count(DISTINCT 字段), 统计不重复的数据总数
- Avg - 求平均值
- Sum - 求和
- Max - 求最大值
- Min - 求最小值
4.上货 (需求:用户搜索热词检索出搜索最多的Top10)
1.首先检索热词,用户在input框输入的时候,每点查询,数据的信息都需要入库,好在咱们es中统计热词
2.插入就不展示了,就说说简单的热词如何分组排序显示。
3.Kibana操作
//先分组看结果 这很关键 是思想的提示
GET XXXXXX/_search
{
"size": 0,
"aggs": {
"order_by_word": { //起的别名
"terms": {
"field": "word",
"size": 10
}
}
}
}
//结果展示
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 69,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"order_by_word" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 5,
"buckets" : [ //buckets 桶 下面都是一个桶内不同类型的分桶
{
"key" : "宝马",
"doc_count" : 19 //这就是上面说的默认是Value_count自动聚合分组后的各数量
}, 我们就是根据这个数量分组后再来排序的不过默认这个关键字为"_count"
{
"key" : "奥迪",
"doc_count" : 18
},
{
"key" : "奔驰",
"doc_count" : 16
},
{
"key" : "讴歌",
"doc_count" : 3
},
{
"key" : "兰博基尼",
"doc_count" : 2
},
{
"key" : "凯迪拉克",
"doc_count" : 2
},
{
"key" : "雷克萨斯",
"doc_count" : 1
},
{
"key" : "雅迪电动车",
"doc_count" : 1
},
{
"key" : "追风鸟电动车",
"doc_count" : 1
},
{
"key" : "艾玛电动车",
"doc_count" : 1
}
]
}
}
}
GET lhzz_hot_word/_search
{
"size": 0,
"aggs": {
"order_by_word": {
"terms": {
"field": "word",
"size": 10,
"order": { //排序 结果和上面一样 默认采用也是倒序
"_count": "desc"
}
}
}
}
}
我觉得这样再看Java操作就很好理解了 ↓ ↓ ↓ ↓ ↓ ↓
4.Java操作
//搜索索引请求
SearchRequest searchRequest = new SearchRequest("XX_nb_hot_words");
//创建条件数据源
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//聚合查询 top10热词
TermsAggregationBuilder field = AggregationBuilders.terms("order_by_word").field("word")
//显示满足条件的前10条记录
.size(10)
//排序 false是降序 true为升序
.order(BucketOrder.aggregation("_count", false));
//把聚合条件 添加至 数据源
sourceBuilder.aggregation(field);
//把数据源 添加至 请求中
searchRequest.source(sourceBuilder);
//创建list用于循环接收响应的对象
List<HotWordVO> hotWordList = Lists.newArrayList();
try {
//返回响应
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//获取自己起的聚合名称
Terms terms = response.getAggregations().get("order_by_word");
for (Terms.Bucket bucket : terms.getBuckets()) {
HotWordVO hotWordVO = new HotWordVO();
//咱们指定的 word 字段
String fieldValue = bucket.getKeyAsString();
//咱们指定的 word 字段在该索引出现的次数
long count = bucket.getDocCount();
hotWordVO.setWord(fieldValue);
hotWordVO.setCount(count);
hotWordList.add(hotWordVO);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
将最终结果,包括关键字以及该关键字的出现次数都return给前端,让前端大哥去处理把。
5.福利 (ES聚合用法)
本节只使用了最简单的类似SQL的group by的Es Terms()函数 更多细节有很多
ES常用的桶聚合如下:
1)Terms聚合 - 类似SQL的group by,根据字段唯一值分组
2)Histogram聚合 - 根据数值间隔分组,例如: 价格按100间隔分组,0、100、200、300等等
3)Date histogram聚合 - 根据时间间隔分组,例如:按月、按天、按小时分组
4)Range聚合 - 按数值范围分组,例如: 0-150一组,150-200一组,200-500一组。
提示:桶聚合一般不单独使用,都是配合指标聚合一起使用,对数据分组之后肯定要统计桶内数据,在ES中如果没有明确指定指标聚合,默认使用Value Count指标聚合,统计桶内文档总数。文章来源:https://www.toymoban.com/news/detail-735669.html
6.ES网上学习资料很多都低于7.0,不适用与现在语法很多都废弃了,所以我也是参照大佬来进行一个自我总结,让我们共同勉励,不断进步把!!!文章来源地址https://www.toymoban.com/news/detail-735669.html
到了这里,关于ES聚合查询 基于RestHighLevelClient依赖 Java操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!