Elasticsearch 多欄位聚合 結果封裝為map
阿新 • • 發佈:2019-04-07
elasticsearch版本:6.1.1
資料欄位:
id aac003 yka055 id_drg name_drg id_mdc name_mdc id_depa
索引建立:
//todo 建立索引 private void createIndex(TransportClient client)throws Exception{ CreateIndexRequestBuilder cib=client.admin().indices().prepareCreate("hisms_sz"); // 設定該index的Mapping,可暫時不設定,後面建完index之後再設定也可 cib.addMapping("cz", createMapping()); // 設定該index的Settings配置,常用的有shard數量、副本數 cib.setSettings(createSetting()); cib.execute().get(); System.out.println("----------新增對映成功----------"); } /** * 建立索引--id aac003 yka055 id_drg name_drg id_mdc name_mdc id_depa */ private XContentBuilder createMapping() throws IOException { XContentBuilder mapping = XContentFactory.jsonBuilder() .startObject() .startObject("properties") //設定之定義欄位 .startObject("aac003") .field("type","keyword") //設定資料型別 .endObject() .startObject("yka055") .field("type","double") .endObject() .startObject("name_drg") .field("type","keyword") .endObject() .startObject("id_mdc") .field("type","keyword") .endObject() .startObject("name_mdc") .field("type","keyword") .endObject() .startObject("id_drg") .field("type","text") .startObject("fields") .startObject("id_drg_key") .field("type","keyword") .endObject() .endObject() .endObject() .startObject("id_depa") .field("type","text") .startObject("fields") .startObject("id_depa_key") .field("type","keyword") .endObject() .endObject() .endObject() .startObject("date") .field("type","date") //設定Date型別 .field("format","yyyy-MM-dd HH:mm:ss")//設定Date的格式 .endObject() .endObject() .endObject(); return mapping; }
聚合查詢:
private void getAggsResult(TransportClient client){ SearchResponse agg = client.prepareSearch("hisms_sz") .setTypes("cz") .addAggregation( AggregationBuilders.terms("id_mdc").field("id_mdc").size(26)//設定聚合條件 group by id_mdc,id_drg .subAggregation( AggregationBuilders.terms("name_drg").field("name_drg").size(700) .subAggregation(AggregationBuilders.avg("avg").field("yka055"))// 聚合結果 avg(date .subAggregation(AggregationBuilders.sum("sum").field("yka055")) .subAggregation(AggregationBuilders.min("min").field("yka055")) .subAggregation(AggregationBuilders.count("count").field("aac003")) .subAggregation(AggregationBuilders.cardinality("cardinality").field("aac003")) ) ) .execute().actionGet(); ArrayList<Object> results = results(agg); System.out.println(results.size()); }
呼叫封裝方法:
private ArrayList<Object> results(SearchResponse agg){
Map<String, Aggregation> aggregations = agg.getAggregations().asMap();
ArrayList<Object> objects = new ArrayList<>();
for (Map.Entry<String, Aggregation> entry:aggregations.entrySet()
) {
String key = entry.getKey();
Aggregation value = entry.getValue();
HashMap<String, Object> group = new HashMap<>();
parseAggs(value,group,key,objects);
}
return objects;
}
//解析聚合結果
private ArrayList<Object> parseAggs(Aggregation agg, HashMap<String, Object> group,String field,ArrayList<Object> objects){
if (agg instanceof Terms){
for (Terms.Bucket bucket:((Terms) agg).getBuckets() ){
String keyAsString = bucket.getKeyAsString();
group.put(field,keyAsString);
for (Map.Entry<String, Aggregation> entry :bucket.getAggregations().asMap().entrySet()
) {
String key = entry.getKey();
Aggregation value = entry.getValue();
if (value instanceof Terms){
parseAggs(value,group,key,objects);
}else {
LinkedHashMap<String, Object> map = package2map(bucket);
map.putAll(group);
objects.add(map);
break;
}
}
}
}
return objects;
}
private LinkedHashMap<String, Object> package2map(Terms.Bucket bucket){
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
for (Map.Entry<String, Aggregation> entry :bucket.getAggregations().asMap().entrySet()
) {
String key = entry.getKey();
Aggregation value = entry.getValue();
map.put(key,getvalue(value));
}
return map;
}
//取值
public String getvalue(Aggregation agg){
String type = agg.getType();
String result="";
switch (type){
case "avg":
result=String.valueOf(((InternalAvg) agg).getValue());
break;
case "sum":
result=String.valueOf(((Sum) agg).getValue());
break;
case "value_count":
result=String.valueOf(((InternalValueCount) agg).getValue());
break;
case "min":
result=String.valueOf(((InternalMin) agg).getValue());
break;
case "max":
result=String.valueOf(((InternalMax) agg).getValue());
break;
case "cardinality":
result=String.valueOf(((InternalCardinality) agg).getValue());
break;
default:
result=String.valueOf(agg);
break;
}
return result;
}
封裝後結果為List<Map>,同sql資料庫中查詢的一樣,方便遍歷查詢,不用再迴圈遍歷取