elasticsearch的数据聚合

news2024/11/24 7:58:57

聚合可以让我们极其方便的实现对数据的统计、分析、运算。例如:

  • 什么品牌的手机最受欢迎?

  • 这些手机的平均价格、最高价格、最低价格?

  • 这些手机每月的销售情况如何?

实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近实时搜索效果

聚合种类

聚合常见的有三类:

  • 桶(Bucket)聚合:用来对文档做分组

    • TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组

    • Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组

  • 度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等

    • Avg:求平均值

    • Max:求最大值

    • Min:求最小值

    • Stats:同时求max、min、avg、sum等

  • 管道(pipeline)聚合:其它聚合的结果为基础做聚合

注意:参加聚合的字段必须是keyword、日期、数值、布尔类型  

DSL实现聚合

语句

GET /hotel/_search
{
  "size": 0,
  "aggs": {
    "brandAgg": {
    "terms": {
        "field": "brand",
        "size": 20
      }
    }
  }
}
  • 设置size为0,结果中不包含文档,只包含聚合结果
  • aggs定义聚合
  • brandAgg给聚合起个名字
  • terms聚合的类型,按照品牌值聚合,所以选择term
  • field参与聚合的字段
  • terms里面的sezi希望获取的聚合结果数量

发起请求的结果 

聚合结果排序

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为count,并且按照count降序排序。

我们可以指定order属性,自定义聚合的排序方式,按照_count降序排列

GET /hotel/_search
{
  "size": 0, 
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "order": {
          "_count": "desc"  
          },
        "size": 20
      }
    }
  }
}

发起请求的结果, 按照_count降序排列。

限定聚合范围

默认情况下,Bucket聚合是对索引库的所有文档做聚合,但真实场景下,用户会输入搜索条件,因此聚合必须是对搜索结果聚合。那么聚合必须添加限定条件。我们可以限定要聚合的文档范围,只要添加query条件即可。

 只对200元以下的文档聚合

GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "lte": 200  
      }
    }
  }, 
  "size": 0, 
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "size": 20
      }
    }
  }
}

聚合得到的品牌明显变少了  

Metric聚合语法

现在我们需要对桶内的酒店做运算,获取每个品牌的用户评分的min、max、avg等值

 score_stats聚合是在brandAgg的聚合内部嵌套的子聚合。因为我们需要在每个桶分别计算

GET /hotel/_search
{
  "size": 0, 
  "aggs": {
    "brandAgg": { 
      "terms": { 
        "field": "brand", 
        "size": 20
      },
      "aggs": { 
        "score_stats": { 
        "stats": { 
          "field": "score" 
          }
        }
      }
    }
  }
}

我们还可以给聚合结果做个排序,例如按照每个桶的酒店平均分做排序,score_stats.avg对score聚合函数的平均值进行降序排序。

GET /hotel/_search
{
  "size": 0, 
  "aggs": {
    "brandAgg": { 
      "terms": { 
        "field": "brand", 
        "size": 20,
        "order": {
          "score_stats.avg": "desc"
        }
      },
      "aggs": { 
        "score_stats": { 
        "stats": { 
          "field": "score" 
          }
        }
      }
    }
  }
}

小结

aggs代表聚合,与query同级  

聚合必须的三要素:

  • 聚合名称

  • 聚合类型

  • 聚合字段

聚合可配置属性有:

  • size:指定聚合结果数量

  • order:指定聚合结果排序方式

  • field:指定聚合字段

java代码实现聚合

搜索页面的品牌、城市等信息不应该是在页面写死,而是通过聚合索引库中的酒店数据得来的  

controller类



import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import cn.itcast.hotel.service.IHotelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/hotel")
public class HotelController {

    @Autowired
    private IHotelService hotelService;


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

service类



import cn.itcast.hotel.mapper.HotelMapper;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;

import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {

    @Autowired
    private RestHighLevelClient client;

    

    @Override
    public Map<String, List<String>> getFilters(RequestParams params) {
        try {
            // 1.准备Request
            SearchRequest request = new SearchRequest("hotel");
            // 2.准备DSL
            // 2.1.query
            // buildBasicQuery(params, request);
            // 2.2.设置size
            request.source().size(0);
            // 2.3.聚合
            buildAggregation(request);
            // 3.发出请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4.解析结果
            Map<String, List<String>> result = new HashMap<>();
            Aggregations aggregations = response.getAggregations();
            // 4.1.根据品牌名称,获取品牌结果
            List<String> brandList = getAggByName(aggregations, "brandAgg");
            result.put("品牌", brandList);
            // 4.2.根据品牌名称,获取品牌结果
            List<String> cityList = getAggByName(aggregations, "cityAgg");
            result.put("城市", cityList);
            // 4.3.根据品牌名称,获取品牌结果
            List<String> starList = getAggByName(aggregations, "starAgg");
            result.put("星级", starList);

            return result;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    private void buildAggregation(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> 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;
    }
   
   
}

发送请求,获得结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/974293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文件夹改名利器!批量随机重命名并自定义长度

你是否曾经为如何快速有效地重命名多个文件夹而感到困扰&#xff1f;我们为您带来了一款强大的文件夹改名工具&#xff0c;让您轻松实现批量随机重命名&#xff0c;并自定义长度&#xff0c;让您的文件夹管理更加高效便捷 首先第一步&#xff0c;我们要打开文件批量改名高手并登…

RLHF不再需要人类,AI 实现标注自循环

从人类反馈中强化学习&#xff08;RLHF&#xff09;在使大型语言模型&#xff08;LLMs&#xff09;与人类偏好保持一致方面非常有效&#xff0c;但收集高质量的人类偏好标签是一个关键瓶颈。我们进行了RLHF与来自AI反馈的强化学习&#xff08;RLAIF&#xff09;的头对头比较 - …

Redis基础知识(三):缓存穿透、缓存击穿、缓存雪崩

文章目录 一、缓存穿透出现过程解决方法 二、缓存击穿出现过程解决方法 三、缓存雪崩出现过程解决方法 我们在项目中大量使用Redis承接海量数据的冲击&#xff0c;但是使用过程中也会遇到一些特殊的情况&#xff0c;这个就是缓存击穿、缓存穿透、缓存雪崩。 一、缓存穿透 缓存…

ApachePulsar原理解析与应用实践(学习笔记一)

随着时代的发展&#xff0c;软件设计的理念也在不断发展&#xff0c;从单体服务、面向服务、微服务&#xff0c;发展到云原生以及无服务。其演变的过程是一个能力不断增强&#xff0c;领域边界不断微分细化的过程。比如无服务就是将函数作为服务&#xff0c;就类似dns模式的服务…

RK3568开发笔记(六):开发板烧写ubuntu固件(支持mipi屏镜像+支持hdmi屏镜像)

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/132686096 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

【Python】pytorch,CUDA是否可用,查看显卡显存剩余容量

CUDA可用&#xff0c;共有 1 个GPU设备可用。 当前使用的GPU设备索引&#xff1a;0 当前使用的GPU设备名称&#xff1a;NVIDIA T1000 GPU显存总量&#xff1a;4.00 GB 已使用的GPU显存&#xff1a;0.00 GB 剩余GPU显存&#xff1a;4.00 GB PyTorch版本&#xff1a;1.10.1cu102 …

webpack实战:某网站JS逆向分析

文章目录 1. 写在前面2. 抓包分析3. 扣加密代码 1. 写在前面 好的逆向能够帮助我们了解加密实现&#xff0c;然后根据加密方式&#xff08;md5,base64,res,des,rsa…)还原加密算法的过程。可以看看我之前的这篇文章&#xff1a;快速定位查找加密方式特征与技巧 目标站点&#…

Qt应用开发(基础篇)——向导对话框 QWizard

一、前言 QWizard类继承于QDialog&#xff0c;为有向导界面需求的应用环境提供了一个框架。 对话框窗口 QDialog QWizard向导对话框是一个拥有队列界面的特殊对话框&#xff0c;向导的目的是引导用户一步一步的完成预设的流程。向导常用于软件安装界面向导、硬件线路安装向导、…

【Linux】Ubuntu20.04版本配置pytorch环境2023.09.05【教程】

【Linux】Ubuntu20.04版本配置pytorch环境2023.09.05【教程】 文章目录 【Linux】Ubuntu20.04版本配置pytorch环境2023.09.05【教程】一、安装Anaconda虚拟环境管理器二、创建虚拟环境并激活三、安装Pytorch四、测试pytorchReference 一、安装Anaconda虚拟环境管理器 首先进入…

《西方美学史》分享1

《西方美学史》分享1 这本书是岭南大学中文系教授许子东老师推荐的&#xff0c;而且这本书名气也非常大。 刚读完绪论和第一章。 这本书可以带领我们去思考&#xff0c;现实社会中“美”是什么&#xff0c;什么是美的。我们总在说“真善美”&#xff0c;“真”和“善”就是美…

恒运资本:光刻胶概念强势拉升,同益股份、格林达涨停,容大感光等走高

光刻胶概念5日盘中强势拉升&#xff0c;到发稿&#xff0c;同益股份、格林达涨停&#xff0c;波长光电、晶瑞电材涨超7%&#xff0c;容大感光涨逾5%&#xff0c;华懋科技、茂莱光学、苏大维格、南大光电等均走强。 消息面上&#xff0c;据新加坡《联合早报》网站9月2日报导&am…

恒运资本:北交所股票全红!不到10分钟30%涨停,“认房不认贷”发力了!

今天早盘&#xff0c;A股震荡上扬&#xff0c;上证指数、深证成指等重要股指高开高走&#xff0c;并均涨超1%&#xff0c;两市成交略有增加。 盘面上&#xff0c;房地产、家居用品、煤炭、钢铁等板块涨幅居前&#xff0c;光刻机、软件服务、半导体、机器视觉等板块跌幅居前。北…

k8s 搭建基于session模式的flink集群

1.flink集群搭建 不废话直接上代码&#xff0c;都是基于官网的&#xff0c;在此记录一下 Kubernetes | Apache Flink flink-configuration-configmap.yaml apiVersion: v1 kind: ConfigMap metadata:name: flink-configlabels:app: flink data:flink-conf.yaml: |jobmanager…

sa-token学习

官方文档地址&#xff1a;sa-token

解决六大痛点促进企业更好使用生成式AI,亚马逊云科技顾凡采访分享可用方案

亚马逊云科技大中华区战略业务发展部总经理顾凡在接受21世纪经济报道记者专访时表示&#xff0c;生成式人工智能将从四个方面为企业带来机遇&#xff1a;第一是创造全新的客户体验&#xff1b;第二是提高企业内部员工的生产力&#xff1b;第三是帮助企业提升业务运营效率&#…

苹果“嘴硬”?下载超出预期,否认开发者对 Vision Pro 兴趣不高

据报道&#xff0c;苹果于上个月在全球多个城市开设了Vision Pro开发者实验室&#xff0c;旨在让开发者尽早体验并研发这款令人期待的头显技术。这一为期一天的实验室活动邀请了一些开发人员前来测试和上手Vision Pro头显&#xff0c;并亲身体验其应用的真实效果。 在活动中&am…

GE HYDRAN M2气体监测系统

气体监测&#xff1a; HYDRAN M2系统能够监测变压器或油冷却电缆系统中的气体&#xff0c;包括氢气、乙炔、甲烷、乙烷和乙烯等。这些气体的生成和积累可能是绝缘材料故障的迹象。 实时监测&#xff1a; 该系统能够实时监测气体浓度的变化&#xff0c;以及油的温度和压力等参数…

软考·系统架构师——导学

文章目录 考试简介考试安排考试科目《综合知识》考点分布历年案例分析考点历年论文考点 最新消息&#xff1a;自2023年下半年起&#xff0c;计算机软件资格考试的考试方式均由纸笔考试改革为计算机化考试。 考试简介 计算机技术与软件专业技术资格&#xff08;水平&#xff09;…

前端 -- 基础 常用标签 ( 标题标签、段落标签、换行标签 )

标题标签 <h1> - <h6> HTML 提供了 6 个等级的网页标题&#xff0c;即 <h1> - <h6> <h1> 我是一级标题 </h1> 单词 head 的缩写&#xff0c;意味 头部&#xff0c;标题 。 上示&#xff0c;即 你在 <h1> </h1> 两个…

【java】【项目实战】[外卖十二]【完结】项目优化(前后端分离开发)

目录 一、问题说明 二、前后端分离开发 1、介绍 2、开发流程 3、前端技术栈 三、Yapi 1、介绍 2、部署 3、使用 3.1 添加项目​编辑 3.2 添加分类​编辑 3.3 添加接口 3.4 运行 3.5 导出接口 3.6 导入数据 四、Swagger 1、介绍 2、使用方式 2.1 pom 2.2 导入…