当前位置: 首页 > news >正文

ES聚合学习(三)

es聚合

#ES中的聚合操作 参与聚合的字段必须是keword、数值、日期、布尔
#1.Bucket桶聚合(文档字段分组,日期分组)2.Metric度量聚合(最大值,最小值,平均值)
#3.Pipeline管道聚合(其他聚合的结果为基础做聚合)

#桶聚合 第一个size:聚合中不包含文档,只包含聚合结果。size:希望获得聚合结果的数量  doc_count:是文档数量,桶里面有几条文档啊,是倒叙排序
#统计所有数据中酒店品牌有几种
GET /hotel/_search
{
  "size":0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "size": 10
      }
    }
  }
}

#更改排序、添加限定聚合搜索的范围
GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 0,
        "lte": 200
      }
    }
  }, 
  "size":0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "order": {
          "_count": "asc"
        }, 
        "size": 10
      }
    }
  }
}


#Metrics聚合
#统计每个品牌用户的评分的最大值、最小值  排序根据平均降序分排序
#里面的aggs是对brand的子聚合,也就是分组后对分组分别计算 stats:可以计算min、max、avg...
GET /hotel/_search
{
  "size":0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "size": 10,
        "order": {
          "scoreAgg.avg": "desc"
        }
      },
      "aggs":{
        "scoreAgg":{
          "stats": {
            "field": "score"
          }
        }
      }
    }
  }
}
  /**
     *桶聚合
     */
    @Test
    void testAggregation() throws IOException {
        //1.准备request
        SearchRequest request=new SearchRequest("hotel");
        //DSL
        request.source().size(0);
        //聚合
        request.source().aggregation(AggregationBuilders.terms("brandAgg")
                .field("brand")
                .size(10));
        //3发送请求
        SearchResponse response=client.search(request,RequestOptions.DEFAULT);
        //4.解析结果
        System.out.println(response);

        //聚合解析
        Aggregations aggregations = response.getAggregations();//解析结果
        //根据聚合名称获取聚合结果
        Terms brandTerms = aggregations.get("brandAgg");
        //获取Buckets
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
        //遍历
        for (Terms.Bucket bucket:buckets){
            //获取key
            String key = bucket.getKeyAsString();
            System.out.println(key);
        }


    }

多条件聚合:

 //多条件聚合
      @Test
      void contextLoad(){
          Map<String, List<String>> result=hotelService.filters();
          System.out.println(result);
      }

 //多参数聚合:品牌、城市、星级聚合
    @Override
    public Map<String, List<String>> filters() {
        try {
            //准备Request
            SearchRequest request=new SearchRequest("hotel");
            //DSL
            request.source().size(0);
            //聚合
            buildAggregations(request);

            //3发送请求
            SearchResponse response=restHighLevelClient.search(request,RequestOptions.DEFAULT);
            //4.解析结果
            System.out.println(response);

            //聚合解析
            Map<String, List<String>> result=new HashMap<>();
            Aggregations aggregations = response.getAggregations();//解析结果
            List<String> brandList = getAggregationByName(aggregations,"brandAgg");
            result.put("品牌",brandList);
            List<String> cityList = getAggregationByName(aggregations, "cityAgg");
            result.put("城市",cityList);

            List<String> starList = getAggregationByName(aggregations, "starAgg");
            result.put("星级",starList);

            return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //聚合封装
    private void buildAggregations(SearchRequest request) {
        request.source().aggregation(AggregationBuilders
                .terms("brandAgg")
                .field("brand")
                .size(100));

        request.source().aggregation(AggregationBuilders
                .terms("cityAgg")
                .field("city")
                .size(100));

        request.source().aggregation(AggregationBuilders
                .terms("starAgg")
                .field("starName")
                .size(100));
    }


    //封装解析方法
    private List<String> getAggregationByName(Aggregations aggregations, String aggName) {
        // 4.1.根据聚合名称,获取聚合结果
        Terms terms = aggregations.get(aggName);
        // 4.2.获取buckets
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        // 4.3.遍历
        List<String> list = new ArrayList<>(buckets.size());
        for (Terms.Bucket bucket : buckets) {
            String brandName = bucket.getKeyAsString();
            list.add(brandName);
        }
        return list;
    }

查询酒店数据的请求

 

filters:查询酒店过滤项的请求

他们两个查询携带的参数是一样的

过滤项查询也要带条件,过滤项查询将来需要聚合来实现 ,聚合一旦加了条件,是在限定聚合的范围 

发现这两个请求携带的参数是一样的为什么查过滤项的时候也要带条件呢?过滤项查询要通过聚合来实现,聚合一带上条件就来限定聚合的范围,为何要限定范围呢?直接对整个索引库做聚合不行呢?

在搜索是没有加条件,搜索的是索引库的所有数据,对所有数据做聚合得到城市和品牌没有问题,但是当输入内容虹桥,得到的数据一定是跟上海虹桥有关的结果

上海虹桥有关的城市对应的一定是上海,但是对索引库的所有数据做聚合,得到的城市一定包含所有的城市,所以用户一定就很奇怪拉,命名搜索的是上海的还能出现北京的?如果再点击北京在结合搜索条件虹桥,能搜到任何东西吗?肯定是不能的北京没有虹桥,所以说不应该对索引库的所有字段做聚合,用户条件是虹桥,就应该对虹桥相关的酒店做聚合,限定聚合的范围,需要加查询条件,查询时用什么条件聚合时也用什么条件,这样就是在酒店的基础上做聚合,这样查询结果就更精确了因此,在查询过滤项时和查询时要用相同的条件

 @PostMapping("filters")
    public Map<String, List<String>> getFilters(@RequestBody RequestParams params) {
        return hotelService.getFilters(params);
    }

 

 @Override
    public Map<String, List<String>> getFilters(RequestParams params) {
        try {
            //准备Request
            SearchRequest request=new SearchRequest("hotel");
            //请求参数 query
            buildBasicQuery(params,request);

            //DSL
            request.source().size(0);
            //聚合
            buildAggregations(request);

            //3发送请求
            SearchResponse response=restHighLevelClient.search(request,RequestOptions.DEFAULT);
            //4.解析结果
            System.out.println(response);

            //聚合解析
            Map<String, List<String>> result=new HashMap<>(3);
            Aggregations aggregations = response.getAggregations();//解析结果
            List<String> brandList = getAggregationByName(aggregations,"brandAgg");
            result.put("brand",brandList);
            List<String> cityList = getAggregationByName(aggregations, "cityAgg");
            result.put("city",cityList);

            List<String> starList = getAggregationByName(aggregations, "starAgg");
            result.put("starName",starList);

            return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

相关文章:

  • git上传文件到远程库
  • 解决 uniapp 开发中权限申请同步告知目的问题| 华为应用商店上架审核问题解决
  • 安装和管理最新的Python3环境(以Mac为例)
  • Docker 数据卷管理
  • Spring 如何管理 Bean 的生命周期?
  • 11--华为防火墙Easy-IP实现原理与配置全解:从“翻译官“到“流量导演“的奇幻之旅(包你看一遍全记住)
  • Django REST Framework 请求封装源码解析与实现流程
  • 1、环境初始化--Linux安装dockerCE
  • Java 集合框架:从数据结构到性能优化,全面解析集合类
  • JavaScript基础-API 和 Web API
  • HIVE安装(详细教程)
  • Python实战(4)-网络编程
  • Liunx系统Microsoft SQL Server数据库还原
  • datawhale组队学习-大语言模型-task5:主流模型架构及新型架构
  • CentOS与Rocky 命令区别
  • python如何获取html中附件链接,并下载保存附件
  • 1.向量数据库milvus standalone单机版搭建
  • MobaXterm:全能终端工具如何重新定义远程开发与运维效率?
  • Linux 常用命令 - last 【显示历史登录用户列表】
  • 在coze工作流中将数据回写到飞书表格
  • 淄博一酒店房间内被曝发现摄像头,当地警方已立案调查
  • 老字号“逆生长”,上海制造的出海“蜜”钥
  • 南昌上饶领导干部任前公示:2人拟提名为县(市、区)长候选人
  • 复原展出孙吴大墓,江苏首座考古博物馆将开放
  • 四部门:强化汛期农业防灾减灾,奋力夺取粮食和农业丰收
  • 白天气温超30℃的北京,晚间下起了冰雹