最近用到es做人群畫像现横,原始數(shù)據(jù)是帶標簽的pin包,為了方便查詢乌企,對數(shù)據(jù)做了預處理虑润,按標簽做聚合,由于標簽的數(shù)量不固定加酵,所以想起來用遞歸實現(xiàn)多字段聚合(三個及三個以上字段)拳喻,源碼在此,方便大家參閱虽画。類似group by field1,field2,field3...
Note:groupFields存放聚合的字段
List<String> groupFields = new ArrayList<>();
groupFields.add("字段1");
groupFields.add("字段2");
groupFields.add("字段3");
TermsBuilder termsBuilder = AggregationBuilders.terms(groupFields.get(0)).field(groupFields.get(0)).size(100);
subAgg(groupFields, termsBuilder, 0);
SearchResponse response = client.prepareSearch(INDEX_NAME).addAggregation(termsBuilder).setSize(0).execute().actionGet(60000);
Terms terms = response.getAggregations().get(groupFields.get(0));
for (Terms.Bucket bucket : terms.getBuckets()) {
StringBuilder builder = new StringBuilder();
builder.append(bucket.getKey()).append("\t");
resolveResult(bucket, groupFields, builder);
}
//拼裝聚合條件
private void subAgg(List<String> list, TermsBuilder termsBuilder, int count) {
if (count < list.size() - 1) {
count ++;
TermsBuilder termsBuilder1 = AggregationBuilders.terms(list.get(count)).field(list.get(count)).size(GROUP_SIZE);
termsBuilder.subAggregation(termsBuilder1);
subAgg(list, termsBuilder1, count);
}
}
//聚合結(jié)果解析
private void resolveResult(Terms.Bucket bucket, List<String> list, StringBuilder keys) {
boolean flag = false;
for (String field : list) {
Terms terms = bucket.getAggregations().get(field);
if (terms != null) {
for (Terms.Bucket bucket1 : terms.getBuckets()) {
StringBuilder keys1 = new StringBuilder();
keys1.append(keys).append(bucket1.getKey()).append("\t");
resolveResult(bucket1, list, keys1);
}
flag = true;
break;
}
}
if (!flag) {
String record =
LOGGER.info("keys = {}", keys);
}
}