微服务——es数据聚合+RestClient实现聚合

数据聚合

聚合的种类

DSL实现Bucket聚合

如图所示,设置了10个桶,那么就显示了数量最多的前10个桶,品牌含有7天酒店的有30家,

品牌含有如家的也有30家。

修改排序规则

限定聚合范围

DSL实现Metrics聚合

如下案例要求对不同的品牌进行统计,所以要进行分组。

如图所示,要对桶的平均评分做排序,要使用不同桶的平均评分

RestClient实现聚合

请求组装

java 复制代码
    @Test
    void testAggregation() throws IOException {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSl
        //2.1设置size
        request.source().size(0);
        //2.2聚合
        request.source().aggregation(AggregationBuilders
                .terms("brandAgg")
                .field("brand")
                .size(10)
        );
        //3.发出请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.解析结果
        System.out.println(response);
    }

结果解析

java 复制代码
    @Test
    void testAggregation() throws IOException {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSl
        //2.1设置size
        request.source().size(0);
        //2.2聚合
        request.source().aggregation(AggregationBuilders
                .terms("brandAgg")
                .field("brand")
                .size(10)
        );
        //3.发出请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.解析结果
        Aggregations aggregations = response.getAggregations();
        //4.1根据聚合名称获取聚合结果
        Terms brandTerms = aggregations.get("brandAgg");
        //4.2获取buckets
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
        //4.3遍历
        for (Terms.Bucket bucket : buckets) {
            //4.4获取key
            String key = bucket.getKeyAsString();
            System.out.println(key);
        }
    }

多条件聚合

在Service中

将公共代码抽取出来,提高复用性

java 复制代码
    @Override
    public Map<String, List<String>> filters() {
        try {
              //1.准备Request
              SearchRequest request = new SearchRequest("hotel");
              //2.准备DSl
              //2.1设置size
              request.source().size(0);
              //2.2聚合
              buildAggregation(request);
              //3.发出请求
              SearchResponse response = client.search(request, RequestOptions.DEFAULT);
              //4.解析结果
              Map<String, List<String>>result=new HashMap<>();
              Aggregations aggregations = response.getAggregations();
              //5.1根据品牌名称获取品牌结果
              List<String> brandList = getAggByName(aggregations,"brandAgg");
              result.put("品牌",brandList);
              //5.2根据品牌名称获取品牌结果
              List<String> cityList = getAggByName(aggregations,"cityAgg");
              result.put("城市",cityList);
              //5.3根据品牌名称获取品牌结果
              List<String> starList = getAggByName(aggregations,"starAgg");
              result.put("星级",starList);
              return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    private static List<String> getAggByName(Aggregations aggregations,String aggName) {
        //4.1根据聚合名称获取聚合结果
        Terms brandTerms = aggregations.get(aggName);
        //4.2获取buckets
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
        //4.3遍历
        List<String>brandList=new ArrayList<>();
        for (Terms.Bucket bucket : buckets) {
            //4.4获取key
            String key = bucket.getKeyAsString();
            brandList.add(key);
        }
        return brandList;
    }

在一个测试类中

java 复制代码
@SpringBootTest
class HotelDemoApplicationTests {

    @Autowired
    private IHotelService hotelService;

    @Test
    void contextLoads() {
        Map<String, List<String>> filters = hotelService.filters();
        System.out.println(filters);
    }

}

运行得到

带过滤条件的聚合

在查询的时候要在查询结果上做聚合,不应该直接将所有数据的聚合结果返回。

所以就是加上query参数。

Controller中

传递的参数和正常参数一模一样

java 复制代码
    @PostMapping("filters")
    public Map<String, List<String>> getFilters(@RequestBody RequestParams Params)
    {
        return hotelService.filters(Params);
    }

Service中

添加传递参数,并且新设置了2.3query,使用搜索时同款的query设置方法

java 复制代码
 @Override
    public Map<String, List<String>> filters(RequestParams Params) {
        try {
              //1.准备Request
              SearchRequest request = new SearchRequest("hotel");
              //2.准备DSl
              //2.1设置size
              request.source().size(0);
              //2.2聚合
              buildAggregation(request);
              //2.3query
            buildBasicQuery(Params, request);
            //3.发出请求
              SearchResponse response = client.search(request, RequestOptions.DEFAULT);
              //4.解析结果
              Map<String, List<String>>result=new HashMap<>();
              Aggregations aggregations = response.getAggregations();
              //5.1根据品牌名称获取品牌结果
              List<String> brandList = getAggByName(aggregations,"brandAgg");
              result.put("品牌",brandList);
              //5.2根据品牌名称获取品牌结果
              List<String> cityList = getAggByName(aggregations,"cityAgg");
              result.put("城市",cityList);
              //5.3根据品牌名称获取品牌结果
              List<String> starList = getAggByName(aggregations,"starAgg");
              result.put("星级",starList);
              return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

结果测试

根据搜索框和过滤条件成功过滤

相关推荐
阿Paul果奶ooo1 小时前
Flink概述
大数据·flink
CDA数据分析师干货分享2 小时前
【CDA 新一级】学习笔记第1篇:数据分析的时代背景
大数据·笔记·学习·数据分析·cda证书·cda数据分析师
软件开发小陈2 小时前
“我店模式”:零售转型中的场景化突围
大数据
计算机毕业设计木哥3 小时前
基于大数据spark的医用消耗选品采集数据可视化分析系统【Hadoop、spark、python】
大数据·hadoop·python·信息可视化·spark·课程设计
xiao-xiang4 小时前
elasticsearch mapping和template解析(自动分词)!
大数据·elasticsearch·搜索引擎
sleetdream5 小时前
Flink DataStream 按分钟或日期统计数据量
大数据·flink
人大博士的交易之路6 小时前
今日行情明日机会——20250813
大数据·数据挖掘·数据分析·缠中说禅·涨停回马枪
Elastic 中国社区官方博客6 小时前
超越相似名称:Elasticsearch semantic text 如何在简洁、高效、集成方面超越 OpenSearch semantic 字段
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
Lx3528 小时前
MapReduce性能调优:从理论到实践的经验总结
大数据·hadoop·后端