JAVA解析ES聚合查询数据结构aggregations关键字

导读:本篇文章讲解 JAVA解析ES聚合查询数据结构aggregations关键字,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

在项目开发中, 有需求需要解析ES的聚合查询结果, 但是没找到有相关内容, 就自己写了一个解析逻辑, 下面贴上代码, 各位复制即可.

ES聚合查询结果示例 [各位可以看看是不是你们目前需要解析的场景]:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 15,
    "successful" : 15,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 14014,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  ################# 就是要解析下面的这个东西 ##################
  "aggregations" : {
    "type" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 13,
          "doc_count" : 14010,
          "level" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : 5,
                "doc_count" : 14010,
                "ccc" : {
                  "value" : 14010
                }
              }
            ]
          }
        },
        {
          "key" : 2,
          "doc_count" : 4,
          "level" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : 5,
                "doc_count" : 4,
                "ccc" : {
                  "value" : 4
                }
              }
            ]
          }
        }
      ]
    }
  }
}

aggregations关键字中的数据结构, 是复杂嵌套类型的.
第一层的type字段, 其实是下面的数据中, 共同拥有的字段信息.
第二层里的buckets里的level字段, 以及第三层里的buckets里的ccc字段, 是我们需要的, 所以按照这个情况, 最后的ccc字段有多少个, 就代表有多少条数据.
并且,最重要的是,最后的ccc里的值, 只有value, 所以, 遍历到value后,就代表到头了.

简单讲, 就是要根据他这个逻辑, 探索其内部结构, 直接上代码!

/**
     * 获取hits字段
     */
    private final String HIST = "hits";
    /**
     * 获取hits中的source字段
     */
    private final String SOURCE = "_source";
    /**
     * 获取聚合查询结果的字段
     */
    private final String AGGREGATIONS = "aggregations";
    /**
     * 获取聚合查询结果字段中的关键字字段
     */
    private final String BUCKETS = "buckets";
    /**
     * 获取聚合查询结果字段中的关键字字段中的值
     */
    private final String KEY = "key";
    /**
     * 获取聚合查询metric类型结果的值
     */
    private final String VALUE = "value";

	/**
     * "探索"ES的aggregations
     * @param resultOverList 提前准备好存放最终数据的集合 (引用传递)
     * @param keyMap 还可以继续进行解析的数据
     * @param resultMap 前面拿到的数据信息
     */
    private void bucketsAnalysis(List<Map<String, Object>> resultOverList, Map.Entry<String, Object> keyMap, Map<String, Object> resultMap) {
        Map<String, Object> valueMap = (Map<String, Object>) keyMap.getValue();
        if (null == valueMap.get(BUCKETS)) {
            //找不到buckets关键字,就只拿value关键字
            resultMap.put(keyMap.getKey(), valueMap.get(VALUE));
            Map<String, Object> overMap = new TreeMap<>(resultMap);
            resultOverList.add(overMap);
            return;
        }
        //拿到第一层buckets
        List<Map<String, Object>> bucketsList = (List<Map<String, Object>>) valueMap.get(BUCKETS);
        for (Map<String, Object> buckets : bucketsList) {
            resultMap.put(keyMap.getKey(), buckets.get(KEY));
            if (buckets.size() <= 2) {
                Map<String, Object> overMap = new TreeMap<>(resultMap);
                resultOverList.add(overMap);
                continue;
            }
            for (Map.Entry<String, Object> map : buckets.entrySet()){
                try {
                    Map<String, Object> testMap = (Map<String, Object>) map.getValue();
                    //*****************************************
                    //在这里又调用了一次当前方法, 去探索其内部结构
                    //*****************************************
                    this.bucketsAnalysis(resultOverList, map, resultMap);
                    break;
                } catch (Exception e) {
                }
            }
        }
    }

	/**
     * 解析ES原生的返回结果
     * @param resultEsMap ES原生的JSON格式返回结果
     * @return 返回最终解析后的数据
     */
    private static List<Map<String, Object>> test(Map<String, Object> resultEsMap) {
        List<Map<String, Object>> resultOverList = new LinkedList<>();
        if (null == resultEsMap || resultEsMap.isEmpty()) {
            return resultOverList;
        }
        Map<String, Object> hitsMap = (Map)resultEsMap.get(HIST);
        List<Map<String, Object>> hitsList = (List) hitsMap.get(HIST);
        //找不到就是聚合,否则普通
        if (null == hitsList || hitsList.isEmpty()) {
            Map<String, Object> aggregationsMap = (Map)resultEsMap.get(AGGREGATIONS);
            for (Map.Entry<String, Object> keyMap : aggregationsMap.entrySet()){
                Map<String, Object> valueMap = (Map<String, Object>) keyMap.getValue();
                Map<String, Object> resultMap = new TreeMap<>();
                if (null == valueMap.get(BUCKETS)) {
                    //找不到buckets关键字,就只拿value关键字
                    resultMap.put(keyMap.getKey(), valueMap.get(VALUE));
                    resultOverList.add(resultMap);
                    return resultOverList;
                }
                this.bucketsAnalysis(resultOverList,keyMap,resultMap);
            }
            return resultOverList;
        }else {
            /**
             * 普通的ES数据结果解析逻辑就不贴了, 有公司里的相关业务逻辑.
             * 普通的就是ES里的 _source字段里的信息, 这个解析不复杂
             */
            return resultOverList;
        }
    }


    public static void main(String[] args) {
        String esJson = "把上面我发的ES的JSON内容复制过来";
        Map<String, Object> resultOver = (Map<String, Object>) JSON.parse(esJson);
        List<Map<String, Object>> result = JestClientUtils.test(resultOver);
        System.out.println(result.toString());
    }

结束~~~~~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/5671.html

(0)

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!