Elasticsearch 聚合查询(Aggregation)详解
Elasticsearch中的聚合查询,类似SQL的SUM/AVG/COUNT/GROUP BY分组查询,主要用于统计分析场景。
实例:
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
// 首先创建RestClient,后续章节通过RestClient对象进行参数配置。
RestClientBuilder restClientBuilder = RestClient.builder(
new HttpHost("localhost", 9200, "http"), // 设置ES服务地址,支持多个
new HttpHost("localhost", 9201, "http"));
// 创建RestHighLevelClient,请求都是通过RestHighLevelClient实例发出去的。
RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);
// 创建SearchRequest对象, 设置查询索引名=order
SearchRequest searchRequest = new SearchRequest("order");
// 通过SearchSourceBuilder构建搜索参数
SearchSourceBuilder builder = new SearchSourceBuilder();
// 通过QueryBuilders构建ES查询条件,这里查询所有文档,复杂的查询语句设置请参考前面的章节。
builder.query(QueryBuilders.matchAllQuery());
// 创建terms桶聚合,聚合名字=by_shop, 字段=shop_id,根据shop_id分组
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("by_shop")
.field("shop_id");
// 嵌套聚合
// 设置Avg指标聚合,聚合名字=avg_price, 字段=price,计算平均价格
aggregationBuilder.subAggregation(AggregationBuilders.avg("avg_price").field("price"));
// 设置聚合查询
builder.aggregation(aggregationBuilder);
// 设置搜索条件
searchRequest.source(builder);
// 如果只想返回聚合统计结果,不想返回查询结果可以将分页大小设置为0
builder.size(0);
// 执行ES请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 处理聚合查询结果
Aggregations aggregations = searchResponse.getAggregations();
// 根据by_shop名字查询terms聚合结果
Terms byShopAggregation = aggregations.get("by_shop");
// 遍历terms聚合结果
for (Terms.Bucket bucket : byShopAggregation.getBuckets()) {
// 因为是根据shop_id分组,因此可以直接将桶的key转换成int类型
int shopId = bucket.getKeyAsNumber().intValue();
// 根据avg_price聚合名字,获取嵌套聚合结果
Avg avg = bucket.getAggregations().get("avg_price");
// 获取平均价格
double avgPrice = avg.getValue();
}
// 关闭ES Client
client.close();
}
}
例子聚合统计的效果等价SQL:
select shop_id, avg(price) as avg_price from order group by shop_id