es 聚合查询入门&范例

public class TestApp {

    public static void main(String[] args) throws Exception {
        Settings settings = Settings.builder()
                .put("cluster.name", "elasticsearch")
                .build();

        TransportClient client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));

//        prepreData(client);

        executeSearch(client);

        client.close();

    }

    private static void prepreData(TransportClient client) throws Exception{
        client.prepareIndex("ball", "player", "1")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "james")
                        .field("age", 33)
                        .field("salary", 3000)
                        .field("team", "cav")
                        .field("position", "sf")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "2")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "irving")
                        .field("age", 25)
                        .field("salary", 2000)
                        .field("team", "cav")
                        .field("position", "pg")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "3")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "curry")
                        .field("age", 29)
                        .field("salary", 1000)
                        .field("team", "war")
                        .field("position", "pg")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "4")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "thompson")
                        .field("age", 26)
                        .field("salary", 2000)
                        .field("team", "war")
                        .field("position", "sg")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "5")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "green")
                        .field("age", 26)
                        .field("salary", 2000)
                        .field("team", "war")
                        .field("position", "pf")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "6")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "garnett")
                        .field("age", 40)
                        .field("salary", 1000)
                        .field("team", "tim")
                        .field("position", "pf")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "7")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "towns")
                        .field("age", 21)
                        .field("salary", 500)
                        .field("team", "tim")
                        .field("position", "c")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "8")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "lavin")
                        .field("age", 21)
                        .field("salary", 300)
                        .field("team", "tim")
                        .field("position", "sg")
                        .endObject())
                .get();

        client.prepareIndex("ball", "player", "9")
                .setSource(XContentFactory.jsonBuilder()
                        .startObject()
                        .field("name", "wigins")
                        .field("age", 20)
                        .field("salary", 500)
                        .field("team", "tim")
                        .field("position", "sf")
                        .endObject())
                .get();

    }




//    private static void executeSearch(TransportClient client) {
//        SearchResponse response = client.prepareSearch("ball")
//                .setTypes("player")
//                .setQuery(QueryBuilders.matchQuery("position", "sf"))
//                .setPostFilter(QueryBuilders.rangeQuery("age").from(20).to(40))
//                .setFrom(0).setSize(1)
//                .get();
//
//        SearchHit[] searchHits = response.getHits().getHits();
//        for(int i = 0; i < searchHits.length; i++) {
//            System.out.println(searchHits[i].getSourceAsString());
//        }
//    }

    private static void executeSearch(TransportClient client) {
        //demo1(client);
        //demo2(client);
        //demo3(client);
        demo4(client);
    }

    private static void demo1(TransportClient client) {
//        例如要计算每个球队的球员数,如果使用SQL语句,应表达如下:
//        select team, count(*) as player_count from player group by team;
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
//        queryBuilder.filter(QueryBuilders.rangeQuery("age").from(25).to(30));  where age > 25 and age < 30
        SearchRequestBuilder requestBuilder = client.prepareSearch("ball").setTypes("player").setQuery(queryBuilder).setFrom(0).setSize(10000);
        requestBuilder.addAggregation(AggregationBuilders.terms("team").field("team"));
        try{
            SearchResponse response = requestBuilder.execute().get();
            Aggregations aggregations = response.getAggregations();
            StringTerms buckets = aggregations.get("team");
            for (StringTerms.Bucket bucket : buckets.getBuckets()) {
                System.out.println(bucket.getKeyAsString() + " : " + bucket.getDocCount());
            }

        }catch (Exception e){
            // log.error ..
            System.err.print(e);
        }
    }


    private static void demo2(TransportClient client) {
//        例如要计算每个球队每个位置的球员数,如果使用SQL语句,应表达如下:
//        select team, position, count(*) as pos_count from player group by team, position;
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        SearchRequestBuilder requestBuilder = client.prepareSearch("ball").setTypes("player").setQuery(queryBuilder).setFrom(0).setSize(10000);
        //指定别名和分组的字段
        TermsAggregationBuilder aggregator = AggregationBuilders.terms("team").field("team");
        TermsAggregationBuilder aggregator2 = AggregationBuilders.terms("position").field("position");
        //添加两个聚合构建器
        requestBuilder.addAggregation(aggregator.subAggregation(aggregator2));
        try{
            //执行查询
            SearchResponse response = requestBuilder.execute().actionGet();
            //将查询结果放入map中
            Map<String, Aggregation> aggMap = response.getAggregations().getAsMap();
            //根据属性名到map中查找
            StringTerms buckets = (StringTerms) aggMap.get("team");
            for (StringTerms.Bucket bucket : buckets.getBuckets()) {
                //先按球队进行分组
                String team = (String) bucket.getKey();
                Map<String, Aggregation> subAggMap = bucket.getAggregations().getAsMap();
                StringTerms positions = (StringTerms) subAggMap.get("position");
                //因为一个球队有很多位置,那么还要依次拿出位置信息
                for (StringTerms.Bucket posBucket : positions.getBuckets()) {
                    //拿到位置的名字
                    String pos = (String) posBucket.getKey();
                    //拿出该位置的数量
                    long docCount = posBucket.getDocCount();
                    //打印球队,位置,人数
                    System.out.println(team + " " + pos + " " + docCount);
                }
            }
        }catch (Exception e){
            // log.error ..
            System.err.print(e);
        }
    }


    private static void demo3(TransportClient client) {
//    例如要计算每个球队年龄最大/最小/总/平均的球员年龄,如果使用SQL语句,应表达如下:
//    select team, max(age) as max_age from player group by team;
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        SearchRequestBuilder requestBuilder = client.prepareSearch("ball").setTypes("player").setQuery(queryBuilder).setFrom(0).setSize(10000);
        AggregationBuilder aggregator = AggregationBuilders.terms("team").field("team");
        MaxAggregationBuilder ageAgg = AggregationBuilders.max("max_age").field("age");
        requestBuilder.addAggregation(aggregator.subAggregation(ageAgg));
        try{
            SearchResponse response = requestBuilder.execute().actionGet();
            Map<String, Aggregation> aggMap = response.getAggregations().getAsMap();
            StringTerms buckets = (StringTerms) aggMap.get("team");
            for (StringTerms.Bucket bucket : buckets.getBuckets()) {
                //先按球队进行分组
                String team = (String) bucket.getKey();
                Map<String, Aggregation> subAggMap = bucket.getAggregations().getAsMap();
                InternalMax ages = (InternalMax)subAggMap.get("max_age");
                System.out.println(team + " " + ages.getValue());
            }

        }catch (Exception e){
            // log.error ..
            System.err.print(e);
        }
    }


    private static void demo4(TransportClient client){
        //聚合后对Aggregation结果排序
        //例如要计算每个球队总年薪,并按照总年薪倒序排列,如果使用SQL语句,应表达如下:
        //select team, sum(salary) as total_salary from player group by team order by total_salary desc;
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        SearchRequestBuilder requestBuilder = client.prepareSearch("ball").setTypes("player").setFrom(0).setSize(10000).setQuery(queryBuilder);
        AggregationBuilder aggregation1 = AggregationBuilders.terms("team").field("team").order(Terms.Order.aggregation("total_salary", false));
        SumAggregationBuilder aggregation2 = AggregationBuilders.sum("total_salary").field("salary");
        requestBuilder.addAggregation(aggregation1.subAggregation(aggregation2));

        try {
            SearchResponse response = requestBuilder.execute().actionGet();
            Map<String, Aggregation> aggMap = response.getAggregations().getAsMap();
            StringTerms terms = (StringTerms) aggMap.get("team");

            for (StringTerms.Bucket term : terms.getBuckets()){
                String team = (String) term.getKey();
                Map<String, Aggregation> subAggMap = term.getAggregations().getAsMap();
                InternalSum sumSalary = (InternalSum) subAggMap.get("total_salary");
                System.out.println(team + " " + sumSalary.getValue());
            }
        }catch (Exception e){
            System.err.println(e);
        }
        
    }


}

版权声明:本文为sz457763638原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。