聚合操作指的是在数据查找基础上对于数据进一步整理筛选行为,聚合操作也属于护具的查询筛选范围。
方法 | 功能 |
---|---|
avg(字段名) | 该字段的平均值 |
max(字段名) | 该字段的最大值 |
min(字段名) | 该字段的最小值 |
sum(字段名) | 该字段所有记录的和 |
count(字段名) | 统计该字段的记录个数 |
eg1 : 找出表中的最大攻击力国家的值?
select max(attack) from countries;
注意: 此时select 后只能写聚合函数,无法查找其他字段,除非该字段值全都一样。(否则写了其他的属性,其他字段只返回那个字段的第一行数据。)
group by
给查询的结果分组
e.g. : 计算每个国家的平均攻击力
select country,avg(attack) from countries group by country;
having语句
对分组聚合后的结果进行进一步筛选
eg1 : 找出平均攻击力大于105的国家的前2名,显示国家名称和平均攻击力
select country,avg(attack) from countries group by country having avg(attack) > 105 order by avg(attack) desc limit 2;
注意:
SQL语句的执行顺序
第一步:from 选择表
第二步:where 筛选条件,筛选对象–行
第三步:group by 将筛选出来的数据进行分组
第四步:having 筛选条件,筛选对象–组
第五步:select 选取最后的结果
第六步:order by 将结果按照特定顺序排列
聚合函数是针对结果集的,但是where条件并不是在查询出结果集之后运行的,所以“聚合函数”不能放在where条件中;
而因为having是对于结果集进行分组,所以聚合函数可以放在having中。
聚合查询可以将数据汇总为度量、统计或其他分析。
聚合查询主要分为三个类别:
在Elasticsearch的聚合中需要掌握两个核心的概念:桶(bucket)、指标(metric)
桶(bucket): 满足特定条件的文档的集合
指标(metric): 对桶内的文档进行聚合分析的操作
(ps:每个聚合都是一个或者多个桶和零个或者多个指标的组合。)
翻译成粗略的SQL语句来解释的话:
SELECT COUNT(color) —> 相当于指标
FROM table
GROUP BY color —>2 相当于桶
桶在概念上类似于SQL的分组(GROUP BY),而指标则类似于COUNT()、SUM()、MAX()等统计方法。
GET /my-index-000001/_search
{
"aggs": {
"my-agg-name": {
"terms": {
"field": "my-field"
}
}
}
}
说明:
aggs 说明采用的是聚合查询
my-agg-name 是聚合查询的名称
terms 说明采用的是Terms aggregation多值聚合:一个基于多桶值源的聚合,其中桶是动态构建的——每个唯一值一个桶。统计每个唯一值的个数。
field 指定需要统计的字段。
对于text类型字段,fields中添加一个keyword,以及fields相关的属性详解,官网教程
官网对于fields属性作用的中文翻译:fields字段经常使用于用于不同目的索引相同字段。这是使用多字段的目的。举个例子,一个字符串类型能够被映射成text类型方便全文搜索,同时他也可以在排序或者聚合查询时被当做keyword类型。
PUT my-index-000001
{
"mappings": {
"properties": {
"city": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
在已经构建了索引,想要在原索引的text字段的fields属性上再添加一个keyword多字段
1.查看索引类型结构
GET /my_index/_mapping查询结果: { “my_index” : {
“mappings” : {
“_meta” : { },
“_source” : {
“includes” : [ ],
“excludes” : [ ]
}
“numeric_detection” : false,
“properties” : {
…
“my_field” : {
“type” : “text”
} } }
2.添加keyword类型
PUT /my_index/_mapping
{
"properties": {
"my_field": {
"type": "text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
}
}
}
但是在已经构建了索引,想要在原索引的text字段的fields属性上再添加一个keyword多字段。在添加之前的数据还是无法进行“聚合”、“排序”操作,只有在添加了多字段后的数据才可以被“聚合”、“排序”。
import org.elasticsearch.client.RestHighLevelClient;
@Autowired
RestHighLevelClient restHighLevelClient;//把RestHighLevelClient放入spring容器中管理
//1、创建查询请求对象
SearchRequest searchRequest = new SearchRequest("参数是es索引名");
//2、创建搜索条件 builder对象 加入大多数搜索参数,提供在search中的request body的设置
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//3、创建聚合查询对象
TermsAggregationBuilder aggBuilder =
AggregationBuilders.terms("参数是聚合查询的builder对象名")
.field("参数是es索引库中的聚合查询字段名")
// 第1个(terms)中的参数名字可以随意取,但是后面用到的时候名字要一一对应
// 第2个(field)中的参数与es库中的聚合查询字段名要完全一致
//4、将聚合查询搜索条件放入Builder对象
searchSourceBuilder.aggregation(aggBuilder);
//5、将条件Builder对象放入searchRequest查询对象之中
searchRequest.source(searchSourceBuilder);
//6、client客户端执行查询,并返回SearchResponse类型的返回结果
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//7.聚合查询 的结果返回
Aggregations aggregations = response.getAggregations();
//8.标记对应分组名,以及该分组的数量
Map<String,Long> group = new HashMap<>();
for (Terms.Bucket bucket : aggregation.getBuckets()) {//这个是每种查询条件下 结果分类循环
//bucket.getKeyAsString() 查到的对应分组类型名
//bucket.getDocCount() 查询到的对应分组对应的数量
group.put(bucket.getKeyAsString(),bucket.getDocCount());
}
包括:javaHighLevelRestClient版本的,以及Transport client版本的