目录
1、现有结构化数据内容如下:
name | age | salary | team | position |
张云雷 | 26 | 2000 | war | pf |
特斯拉 | 20 | 500 | tim | sf |
于谦 | 25 | 2000 | cav | pg |
爱迪生 | 40 | 1000 | tim | pf |
爱因斯坦 | 21 | 300 | tim | sg |
郭德纲 | 33 | 3000 | cav | sf |
牛顿 | 21 | 500 | tim | c |
岳云鹏 | 29 | 1000 | war | pg |
2、初始化一批数据到es索引库当中去
/**
* 批量添加数据
* @throws IOException
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void addIndexDatas() throws IOException, ExecutionException, InterruptedException {
//获取settings,配置es集群的名字
Settings settings = Settings.builder().put("cluster.name", "myes").build();
//创建客户端
TransportAddress transportAddress = new TransportAddress(InetAddress.getByName("node01"), 9300);
TransportAddress transportAddress2 = new TransportAddress(InetAddress.getByName("node02"), 9300);
TransportAddress transportAddress3 = new TransportAddress(InetAddress.getByName("node03"), 9300);
//获取client客户端
TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(transportAddress).addTransportAddress(transportAddress2).addTransportAddress(transportAddress3);
/**
* 创建索引
* */
client.admin().indices().prepareCreate("player").get();
//构建json的数据格式,创建映射
XContentBuilder mappingBuilder = XContentFactory.jsonBuilder()
.startObject()
.startObject("player")
.startObject("properties")
.startObject("name").field("type","text").field("index", "true").field("fielddata","true").endObject()
.startObject("age").field("type","integer").endObject()
.startObject("salary").field("type","integer").endObject()
.startObject("team").field("type","text").field("index", "true").field("fielddata","true").endObject()
.startObject("position").field("type","text").field("index", "true").field("fielddata","true").endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest request = Requests.putMappingRequest("player")
.type("player")
.source(mappingBuilder);
client.admin().indices().putMapping(request).get();
//批量添加数据开始
BulkRequestBuilder bulkRequest = client.prepareBulk();
// either use client#prepare, or use Requests# to directly build index/delete requests
bulkRequest.add(client.prepareIndex("player", "player", "1")
.setSource(jsonBuilder()
.startObject()
.field("name", "郭德纲")
.field("age", 33)
.field("salary",3000)
.field("team" , "cav")
.field("position" , "sf")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "2")
.setSource(jsonBuilder()
.startObject()
.field("name", "于谦")
.field("age", 25)
.field("salary",2000)
.field("team" , "cav")
.field("position" , "pg")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "3")
.setSource(jsonBuilder()
.startObject()
.field("name", "岳云鹏")
.field("age", 29)
.field("salary",1000)
.field("team" , "war")
.field("position" , "pg")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "4")
.setSource(jsonBuilder()
.startObject()
.field("name", "孙越")
.field("age", 26)
.field("salary",2000)
.field("team" , "war")
.field("position" , "sg")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "5")
.setSource(jsonBuilder()
.startObject()
.field("name", "张云雷")
.field("age", 26)
.field("salary",2000)
.field("team" , "war")
.field("position" , "pf")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "6")
.setSource(jsonBuilder()
.startObject()
.field("name", "爱迪生")
.field("age", 40)
.field("salary",1000)
.field("team" , "tim")
.field("position" , "pf")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "7")
.setSource(jsonBuilder()
.startObject()
.field("name", "牛顿")
.field("age", 21)
.field("salary",500)
.field("team" , "tim")
.field("position" , "c")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "8")
.setSource(jsonBuilder()
.startObject()
.field("name", "爱因斯坦")
.field("age", 21)
.field("salary",300)
.field("team" , "tim")
.field("position" , "sg")
.endObject()
)
);
bulkRequest.add(client.prepareIndex("player", "player", "9")
.setSource(jsonBuilder()
.startObject()
.field("name", "特斯拉")
.field("age", 20)
.field("salary",500)
.field("team" , "tim")
.field("position" , "sf")
.endObject()
)
);
BulkResponse bulkResponse = bulkRequest.get();
client.close();
}
3、需求一:统计每个球队当中球员的数量
sql语句实现:select team, count(*) as player_count from player group by team;
@Test
public void groupAndCount() {
//1:构建查询提交
SearchRequestBuilder builder = client.prepareSearch("player").setTypes("player");
//2:指定聚合条件
TermsAggregationBuilder team = AggregationBuilders.terms("player_count").field("team");
//3:将聚合条件放入查询条件中
builder.addAggregation(team);
//4:执行action,返回searchResponse
SearchResponse searchResponse = builder.get();
Aggregations aggregations = searchResponse.getAggregations();
for (Aggregation aggregation : aggregations) {
StringTerms stringTerms = (StringTerms) aggregation;//类型
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();//缓存
for (StringTerms.Bucket bucket : buckets) {
System.out.println(bucket.getKey());
System.out.println(bucket.getDocCount());
}
}
}
4、需求二:统计每个球队中每个位置的球员数量
sql语句实现:select team, position, count(*) as pos_count from player group by team, position;
@Test
public void teamAndPosition(){
//1、构建查询提交
SearchRequestBuilder builder = client.prepareSearch("player").setTypes("player");
//2、指定聚合条件
TermsAggregationBuilder team = AggregationBuilders.terms("player_count").field("team");
TermsAggregationBuilder position = AggregationBuilders.terms("position_count").field("position");
//3、指定多个分组条件的先后顺序关系
team.subAggregation(position);
//4、将聚合条件放入查询条件;并执行action,返回searchResponse
SearchResponse searchResponse = builder.addAggregation(team).addAggregation(position).get();
//5、获取聚合结果
Aggregations aggregations = searchResponse.getAggregations();
//遍历聚合结果
for (Aggregation aggregation : aggregations) {
// System.out.println(aggregation.toString());
StringTerms stringTerms = (StringTerms) aggregation;
List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
//遍历
for (StringTerms.Bucket bucket : buckets) {
long docCount = bucket.getDocCount();
Object key = bucket.getKey();
System.out.println("当前队伍名称为"+key+"该队伍下有"+docCount+"个球员");
Aggregation position_count = bucket.getAggregations().get("position_count");
if (null !=position_count){
StringTerms positionTerm = (StringTerms) position_count;
List<StringTerms.Bucket> buckets1 = positionTerm.getBuckets();
//遍历位置
for (StringTerms.Bucket bucket1 : buckets1) {
Object key1 = bucket1.getKey();
long docCount1 = bucket1.getDocCount();
System.out.println("该队伍下面的位置为"+key1+"该位置下有"+docCount1+"人");
}
}
}
}
}
5、需求三:分组求各种值
计算每个球队年龄最大值:
sql语句:select team, max(age) as max_age from player group by team;
@Test public void groupAndMax(){ //1、构建查询提交 SearchRequestBuilder builder = client.prepareSearch("player").setTypes("player"); //2、指定聚合条件 TermsAggregationBuilder team = AggregationBuilders.terms("team_group").field("team"); TermsAggregationBuilder age = AggregationBuilders.terms("max_age").field("age"); //3、指定多个分组条件的先后顺序关系 team.subAggregation(age); //4、将聚合条件放入查询条件;并执行action,返回searchResponse SearchResponse searchResponse = builder.addAggregation(team).get(); //5、获取聚合结果 Aggregations aggregations = searchResponse.getAggregations(); //遍历聚合结果 for (Aggregation aggregation : aggregations) { StringTerms stringTerms = (StringTerms) aggregation; List<StringTerms.Bucket> buckets = stringTerms.getBuckets(); for (StringTerms.Bucket bucket : buckets) { Aggregation max_age = bucket.getAggregations().get("max_age"); System.out.println(max_age.toString()); } } }
6、需求四:统计每个球队年龄最小值
计算每个球队年龄最大/最小/总/平均的球员年龄
sql:select team, min(age) as min_age from player group by team;
@Test public void teamMinAge(){ //1、构建查询提交 SearchRequestBuilder builder = client.prepareSearch("player").setTypes("player"); //2、指定聚合条件 TermsAggregationBuilder team = AggregationBuilders.terms("team_count").field("team"); TermsAggregationBuilder age = AggregationBuilders.terms("min_age").field("age"); //3、指定多个分组条件的先后顺序关系 TermsAggregationBuilder termsAggregationBuilder = team.subAggregation(age); //4、将聚合条件放入查询条件;并执行action,返回searchResponse SearchResponse searchResponse = builder.addAggregation(termsAggregationBuilder).get(); //5、获取聚合结果 Aggregations aggregations = searchResponse.getAggregations(); for (Aggregation aggregation : aggregations) { // System.out.println(aggregation.toString()); StringTerms stringTerms = (StringTerms) aggregation; List<StringTerms.Bucket> buckets = stringTerms.getBuckets(); for (StringTerms.Bucket bucket : buckets) { Aggregations aggregations1 = bucket.getAggregations(); for (Aggregation aggregation1 : aggregations1) { System.out.println(aggregation1.toString()); } } } }
7、需求五:分组求平均值
计算每个球队年龄最大/最小/总/平均的球员年龄
sql实现:select team, avg(age) as max_age from player group by team;
@Test public void avgTermAge(){ //1、构建查询提交 SearchRequestBuilder builder = client.prepareSearch("player").setTypes("player"); //2、指定聚合条件 TermsAggregationBuilder team_field = AggregationBuilders.terms("player_count").field("team"); AvgAggregationBuilder age_avg = AggregationBuilders.avg("age_avg").field("age"); //3、指定多个分组条件的先后顺序关系 team_field.subAggregation(age_avg); //4、将聚合条件放入查询条件;并执行action,返回searchResponse SearchResponse searchResponse = builder.addAggregation(team_field).get(); //5、获取聚合结果 Aggregations aggregations = searchResponse.getAggregations(); //遍历 for (Aggregation aggregation : aggregations) { System.out.println(aggregation.toString()); StringTerms stringTerms = (StringTerms) aggregation; } }
8、需求六:分组求和
计算每个球队球员的平均年龄,同时又要计算总年薪
sql实现:select team, avg(age)as avg_age, sum(salary) as total_salary from player group by team;
@Test public void avgAndSum(){ //1、构建查询提交 SearchRequestBuilder builder = client.prepareSearch("player").setTypes("player"); //2、指定聚合条件 TermsAggregationBuilder team_group = AggregationBuilders.terms("team_group").field("team"); AvgAggregationBuilder age_avg = AggregationBuilders.avg("age_avg").field("age"); SumAggregationBuilder sumMoney = AggregationBuilders.sum("sum_money").field("salary"); //3、指定多个分组条件的先后顺序关系 TermsAggregationBuilder termsAggregationBuilder = team_group.subAggregation(age_avg).subAggregation(sumMoney); //4、将聚合条件放入查询条件;并执行action,返回searchResponse SearchResponse searchResponse = builder.addAggregation(termsAggregationBuilder).get(); //5、获取聚合结果 Aggregations aggregations = searchResponse.getAggregations(); //遍历 for (Aggregation aggregation : aggregations) { System.out.println(aggregation.toString()); } }
9、需求七:聚合排序
计算每个球队总年薪,并按照总年薪倒序排列
sql实现:select team, sum(salary) as total_salary from player group by team order by total_salary desc;
@Test public void orderBySum(){ //1、构建查询提交 SearchRequestBuilder builder = client.prepareSearch("player").setTypes("player"); //2、指定聚合条件 TermsAggregationBuilder teamGroup = AggregationBuilders.terms("team_group").field("team").order(BucketOrder.count(true)); SumAggregationBuilder sumMoney = AggregationBuilders.sum("sum_money").field("salary"); //3、指定多个分组条件的先后顺序关系 TermsAggregationBuilder termsAggregationBuilder = teamGroup.subAggregation(sumMoney); //4、将聚合条件放入查询条件;并执行action,返回searchResponse SearchResponse searchResponse = builder.addAggregation(termsAggregationBuilder).get(); Map<String, Aggregation> stringAggregationMap = searchResponse.getAggregations().asMap(); System.out.println(stringAggregationMap); //5、获取聚合结果 Aggregations aggregations = searchResponse.getAggregations(); //遍历聚合结果 for (Aggregation aggregation : aggregations) { System.out.println(aggregation.toString()); } }