← 返回首页
聚合案例
发表时间:2024-01-05 06:13:59
聚合案例

聚合案例。

1.aggregations聚合统计

ES中可以实现基于字段进行分组聚合的统计,聚合操作支持count()、sum()、avg()、max()、min()等聚会函数。

下面来看两个案例:

1).统计相同年龄的学员个数

package com.simoniu.db_elasticsearch.aggregations;

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.RestHighLevelClient;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.List;

/**
 * 聚合统计:统计相同年龄的学员个数
 * Created by simoniu
 */
public class EsAggCaseDemo1 {

    public static void main(String[] args) throws Exception{
        //获取RestClient连接
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("master", 9200, "http"),
                        new HttpHost("slave1", 9200, "http"),
                        new HttpHost("slave2", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("myschool");

        //指定查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
              //指定分组信息,默认是执行count聚合
        TermsAggregationBuilder aggregation = AggregationBuilders.terms("age_term")
                .field("age");
        //aggregation.size(Integer.MAX_VALUE);//获得所有分组,默认返回是10个 
        searchSourceBuilder.aggregation(aggregation);
        searchRequest.source(searchSourceBuilder);

        //执行查询操作
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        //获取分组信息
        Terms terms = searchResponse.getAggregations().get("age_term");
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        for (Terms.Bucket bucket: buckets) {
            System.out.println(bucket.getKey()+"---"+bucket.getDocCount());
        }

        //关闭连接
        client.close();
    }
}

运行结果:

19---4
17---2
12---1
15---1
16---1
20---1
21---1
22---1
23---1
28---1

2).统计每个学员的总成绩

初始化score索引数据如下:

curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/1' -d'{"name":"张三","subject":"chinese","score":59}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/6' -d'{"name":"王五","subject":"math","score":68}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/3' -d'{"name":"李四","subject":"chinese","score":78}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/2' -d'{"name":"张三","subject":"math","score":89}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/4' -d'{"name":"李四","subject":"math","score":85}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/5' -d'{"name":"王五","subject":"chinese","score":97}'

java代码实现:

package com.simoniu.db_elasticsearch.aggregations;

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.RestHighLevelClient;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.List;

/**
 * 聚合统计:统计每个学员的总成绩
 * Created by simoniu
 */
public class EsAggCaseDemo2 {

    public static void main(String[] args) throws Exception{
        //获取RestClient连接
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("master", 9200, "http"),
                        new HttpHost("slave1", 9200, "http"),
                        new HttpHost("slave2", 9200, "http")));
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("score");

        //指定查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //指定分组和求sum
        TermsAggregationBuilder aggregation = AggregationBuilders.terms("name_term")
                .field("name.keyword")//指定分组字段,如果是字符串(Text)类型,则需要指定使用keyword类型
                .subAggregation(AggregationBuilders.sum("sum_score").field("score"));//指定求sum,也支持avg、min、max等操作
        searchSourceBuilder.aggregation(aggregation);

        searchRequest.source(searchSourceBuilder);

        //执行查询操作
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        //获取分组信息
        Terms terms = searchResponse.getAggregations().get("name_term");
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        for (Terms.Bucket bucket: buckets) {
            //获取sum聚合的结果
            Sum sum = bucket.getAggregations().get("sum_score");
            System.out.println(bucket.getKey()+"---"+sum.getValue());
        }

        //关闭连接
        client.close();
    }
}

运行结果:

张三---148.0
李四---163.0
王五---165.0