Elasticsearch多字段聚合查询

最近用到es做人群画像,原始数据是带标签的pin包,为了方便查询,对数据做了预处理,按标签做聚合,由于标签的数量不固定,所以想起来用递归实现多字段聚合(三个及三个以上字段),源码在此,方便大家参阅。类似group by field1,field2,field3...

Note:groupFields存放聚合的字段

List 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 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);
        }
    }
//聚合结果解析
private void resolveResult(Terms.Bucket bucket, List 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, bulkProcessor);
                }
                flag = true;
                break;
            }
        }
        if (!flag) {
            String record = 
            LOGGER.info("keys = {}", keys);
        }
    }

你可能感兴趣的:(Elasticsearch多字段聚合查询)