essql聚合结果封装处理

工作中,由于es原生java api对group的支持不是很友好,特别是group by多个字段聚合时,容易java heap space ,而使用essql则不会。但是使用essql多个group by字段,http返回的结果很复杂,嵌套太多,如果每个sql都带有group by字段,则相应的每个方法都要重写一套特定解析规范,重复造轮子,用了一下午时间,写了一套java版本的essql group by返回结果的封装类,动态适配,避免重复造轮子!有喜欢的,请点赞哈!!!

@Override
public Map<String, Object> sqlQuery(String sql) {
    LinkedHashMap resp = null;
    try {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "text/plain");
        headers.set("Authorization", "Basic enpsb2c6T09vSjNvVlVadDVFeHY=");
        HttpEntity<String> entity = new HttpEntity<>(sql, headers);
        resp = restTemplate.postForObject(logUrl, entity, LinkedHashMap.class);
    } catch (Exception e) {
        logger.error("LogRestService | sqlQuery | sql={}", sql, e);
    }
    return resp;
}

/**
 * Handle the query result
 * in case of Aggregation query (SQL group by)
 *
 * @param resMap
 */
public static List<Map<String, Object>> aggregationQueryResultHandler(Map<String, Object> resMap) {
    Map<String, Object> aggregations = (Map<String, Object>) resMap.get("aggregations");
    if (MapUtils.isEmpty(aggregations)) {
        return null;
    }
    return getRows(null, aggregations, new HashMap<>());
}

private static List<Map<String, Object>> getRows(String bucketName, Map<String, Object> bucket, Map<String, Object> dataMap) {
    List<Map<String, Object>> rows = new ArrayList<>();

    List<Map<String, Object>> subBuckets = getSubBuckets(bucket);
    if (subBuckets.size() > 0) {
        subBuckets.forEach(item -> {
            String subBucketName = (String) item.get("bucketName");
            Map<String, Object> subBucket = (Map<String, Object>) item.get("bucket");

            Map<String, Object> newDataMap = new HashMap<>();

            if (StringUtils.isNotBlank(bucketName)) {
                newDataMap.put(bucketName, bucket.get("key"));
                newDataMap.putAll(dataMap);
            }

            List<Map<String, Object>> newRows = getRows(subBucketName, subBucket, newDataMap);
            rows.addAll(newRows);
        });
    } else {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.putAll(dataMap);

        if (StringUtils.isNotBlank(bucketName)) {
            if (bucket.containsKey("key_as_string")) {
                resultMap.put(bucketName, bucket.get("key_as_string"));
            } else {
                resultMap.put(bucketName, bucket.get("key"));
            }
        }

        for (String field : bucket.keySet()) {
            Object bucketValue = bucket.get(field);
            if (bucketValue instanceof Map) {
                Map<String, Object> tempMap = (Map<String, Object>) bucketValue;
                if (tempMap.containsKey("buckets")) {
                    List<Map<String, Object>> newRows = getRows(null, tempMap, new HashMap<>());
                    rows.addAll(newRows);
                    continue;
                }

                if (tempMap.containsKey("value")) {
                    resultMap.put(field, tempMap.get("value"));
                }
            }
        }

        if (MapUtils.isNotEmpty(resultMap)) {
            rows.add(resultMap);
        }
    }
    return rows;
}

private static List<Map<String, Object>> getSubBuckets(Map<String, Object> bucket) {
    List<Map<String, Object>> mapList = new ArrayList<>();
    for (String field : bucket.keySet()) {
        Object obj = bucket.get(field);
        if (obj instanceof Map && ((Map) obj).containsKey("buckets")) {
            List<Map<String, Object>> subList = (List<Map<String, Object>>) ((Map<String, Object>) obj).get("buckets");
            subList.forEach(item -> {
                Map<String, Object> subMap = new HashMap<>();
                subMap.put("bucketName", field);
                subMap.put("bucket", item);
                mapList.add(subMap);
            });
        }
    }
    return mapList;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值