ES聚合统计demo
统计某个字段的和,最小值,最大值,平均值等
GET /shop_order_v3/_search
{
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"range": {
"addTime": {
"gt" : "2019-07-01 00:00:00",
"lt": "2020-07-07 00:00:00"
}
}
},
{ "term": { "storeId": "1" }}
]
}
}
}
},
"size": 1, # 这里设置为1是为了输出文档内容,实际使用设为0
"aggs": {
"paymentPrice_stats": {
"stats": {
"field": "paymentPrice"
}
}
}
}
ES输出
{
"took" : 14,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 333,
"max_score" : 0.0,
"hits" : [
{
"_index" : "shop_order_v3",
"_type" : "_doc",
"_id" : "10939",
"_score" : 0.0,
"_source" : {
# 部分字段
"id" : "10939",
"paymentPrice" : 0.01,
"postage" : 0.0,
"salePrice" : 0.01,
"statusDesc" : "订单已退款",
"statusText" : "快递-已退款",
"storeId" : 1,
"userId" : 245
}
}
]
},
"aggregations" : {
"paymentPrice_stats" : {
"count" : 328,
"min" : 0.01,
"max" : 288.88,
"avg" : 1.9077134146341463,
"sum" : 625.73
}
}
}
java 实现
ES java Client版本是6.7.0
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.7.0</version>
</dependency>
java 实现
// ES日期需要填字符串
String searchYesterdayStartTime = DateFormatUtils.format(DateUtils.getDayStart(DateUtils.yesterday()), DateFormatConstant.YYYY_MM_DD_HH_MM_SS);
String searchYesterdayEndTime = DateFormatUtils.format(DateUtils.getDayEnd(DateUtils.yesterday()), DateFormatConstant.YYYY_MM_DD_HH_MM_SS);
// 构建查询条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder statisticsBoolQuery = QueryBuilders.boolQuery();
BoolQueryBuilder filterBuilder = QueryBuilders.boolQuery();
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("addTime").from(searchYesterdayStartTime).to(searchYesterdayEndTime);
filterBuilder.must(rangeQueryBuilder);
filterBuilder.must(new TermQueryBuilder("storeId", storeId));
statisticsBoolQuery.filter(filterBuilder);
searchSourceBuilder.query(statisticsBoolQuery);
// 设置聚合类型与统计字段
searchSourceBuilder.aggregation(AggregationBuilders.stats("paymentPrice_stat").field("paymentPrice"));
// 隐藏搜索文档
searchSourceBuilder.size(0);
SearchRequest searchRequest = new SearchRequest(esIndexNameConfig.getShopOrder());
searchRequest.types("_doc");
searchRequest.source(searchSourceBuilder);
try {
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
ParsedStats parsedStats = response.getAggregations().get("paymentPrice_stat");
// 获取总和
Double ordersSales = parsedStats.getSum();
// 符合条件的文档数
long ordersCount = parsedStats.getCount();
} catch (IOException e) {
log.error("restHighLevelClient.search error {} ", e);
}
当Aggregation类型为stats时,response的统计结果需要用ParsedStats来接收,该类部分源码如下
package org.elasticsearch.search.aggregations.metrics.stats;
...
import org.elasticsearch.search.aggregations.ParsedAggregation;
...
public class ParsedStats extends ParsedAggregation implements Stats {
protected long count; # 文档数
protected double min; # 最小值
protected double max; # 最大值
protected double sum; # 总和
protected double avg; # 平均值
...
}
设置聚合类型为stats时用ParsedStats来接收,其他聚合模型也都有对应的类。