es 聚合查询入门&范例

tech2025-08-11  36

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); } } }
最新回复(0)