ElasticSearch通过Kibnana做聚合查询

查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资。(M 代表男性 F 代表女性)

GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "genderAgg": {
          "terms": {
            "field": "gender.keyword",
            "size": 10
          },
          "aggs": {
            "balanceAvg": {
              "avg": {
                "field": "balance"
              }
            }
          }
        },
        "ageBalanceAvg":{
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

返回结果,每个年龄按男、女显示客户账面上的平均余额(demo data)

  1. 年龄为31岁的男性客户共有35人,平均余额29565
  2. 年龄为31岁的男性客户共有26人,平均余额26626
  3. 年龄为31岁的客户共61人,平均余额28312

alt


使用SpringBoot进行原生的ElasticSearch聚合查询

````@Test
    public void testAggQuery() throws IOException {
      
        SearchRequest searchRequest = new SearchRequest("goods");
      
        SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
      
        // 1. 查询title包含手机的数据
        MatchQueryBuilder query = QueryBuilders.matchQuery("title", "手机");

        sourceBulider.query(query);
        // 2. 查询品牌列表
        /* 参数:
            1. 自定义的名称,将来用于获取数据
            2. 分组的字段
         */
        AggregationBuilder agg = AggregationBuilders.terms("goods_brands").field("brandName").size(100);
      
        sourceBulider.aggregation(agg);

        searchRequest.source(sourceBulider);
      
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
      
        SearchHits searchHits = searchResponse.getHits();
      
        //获取记录数
        long value = searchHits.getTotalHits().value;
      
        System.out.println("总记录数:"+value);

        List<Goods> goodsList = new ArrayList<>();
      
        SearchHit[] hits = searchHits.getHits();
      
        for (SearchHit hit : hits) {
          
            String sourceAsString = hit.getSourceAsString();
          
            //转为java
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
          
            goodsList.add(goods);
        }

        for (Goods goods : goodsList) {
          
            System.out.println(goods);
          
        }

        // 获取聚合结果
        Aggregations aggregations = searchResponse.getAggregations();
      
        Map<String, Aggregation> aggregationMap = aggregations.asMap();

        //System.out.println(aggregationMap);
      
        Terms goods_brands = (Terms) aggregationMap.get("goods_brands");
      
        List<? extends Terms.Bucket> buckets = goods_brands.getBuckets();

        List<String> brands = new ArrayList();
      
        for (Terms.Bucket bucket : buckets) {
          
            Object key = bucket.getKey();
          
            long docCount = bucket.getDocCount();
          
            String results = "品牌 = " + key + " : 商品数量 = " + docCount;
          
            brands.add(results);
          
        }

        for (String brand : brands) {
          
            System.out.println(brand);
          
        }
      
    }

Spring Data Elasticsearch API 也封装了基本的方法,同时支持自定义查询方法

https://spring.io/projects/spring-data-elasticsearch