elasticsearch的数据聚合
聚合可以让我们极其方便的实现对数据的统计、分析、运算。例如:
什么品牌的手机最受欢迎?
这些手机的平均价格、最高价格、最低价格?
这些手机每月的销售情况如何?
实现这些统计功能的比数据库的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 {@Autowiredprivate 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 {@Autowiredprivate RestHighLevelClient client;@Overridepublic Map<String, List<String>> getFilters(RequestParams params) {try {// 1.准备RequestSearchRequest request = new SearchRequest("hotel");// 2.准备DSL// 2.1.query// buildBasicQuery(params, request);// 2.2.设置sizerequest.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.获取bucketsList<? extends Terms.Bucket> buckets = brandTerms.getBuckets();// 4.3.遍历List<String> brandList = new ArrayList<>();for (Terms.Bucket bucket : buckets) {// 4.4.获取keyString key = bucket.getKeyAsString();brandList.add(key);}return brandList;}}
发送请求,获得结果
相关文章:

elasticsearch的数据聚合
聚合可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些统计功能的比数据库的sql要方便的多,而且…...

【网络编程·数据链路层】MAC帧/以太网协议/ARP协议/RARP协议
需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。 目录 一、MAC帧 1、IP地址和MAC地址的区别 2、MAC帧协议 3、MTU对IP协议的…...

算法:移除数组中的val的所有元素---双指针[2]
文章来源: https://blog.csdn.net/weixin_45630258/article/details/132689237 欢迎各位大佬指点、三连 1、题目: 给你一个数组 nums和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用…...

Python小知识 - Python爬虫进阶:如何克服反爬虫技术
Python爬虫进阶:如何克服反爬虫技术 爬虫是一种按照一定的规则,自动抓取网页信息的程序。爬虫也叫网页蜘蛛、蚂蚁、小水滴,是一种基于特定算法的自动化程序,能够按照一定的规则自动的抓取网页中的信息。爬虫程序的主要作用就是从一…...

SAP中的新旧事务码
SAP中的新旧事务码 SAP随着新版本的发布,我们知道sap已经更新了很多的程序和TCODE。sap提供了很多新的TCODE来替换旧的TCODE,新TCODE有很多的新特性和新功能。在这个这种情况下,很多旧TCODE就会被废弃。我们如何查找这个替换呢? …...

day3_C++
day3_C 思维导图用C的类完成数据结构 栈的相关操作用C的类完成数据结构 循环队列的相关操作 思维导图 用C的类完成数据结构 栈的相关操作 stack.h #ifndef STACK_H #define STACK_H#include <iostream> #include <cstring>using namespace std;typedef int datat…...
力扣题解(73. 矩阵置零),带注释
题目描述 链接:点我 题解 //法一 使用hashset记录有0的横纵坐标即可 class Solution {public void setZeroes(int[][] matrix) {HashSet<Integer> row new HashSet<Integer>();HashSet<Integer> col new HashSet<Integer>();for(int i 0;i <…...

SpringMVC应用
文章目录 一、常用注解二、参数传递2.1 基础类型String2.2 复杂类型2.3 RequestParam2.4.路径传参 PathVariable2.4 Json数据传参 RequestBody2.5 RequestHeader 三、方法返回值3.1 void3.2 Stringmodel3.3 ModelAndView 一、常用注解 SpringMVC是一个基于Java的Web框架&#…...

百度输入法全面升级,打造首个基于大模型的输入法原生应用
基于文心一言,百度输入法宣布全面升级,打造行业首个“基于大模型的输入法原生应用”,从“输入工具”全面转型为“AI创作工具”。 近日,百度文心一言正式向公众开放。基于文心一言,百度输入法宣布全面升级,打…...

如何解决GitHub 访问不了?小白教程
GitHub 是全球最大的代码开源平台,小伙伴们平时都喜欢在那里找一些优质的开源项目来学习,以提升自己的编程技能。 但是很多小白初探GitHub 发现访问不了,不能访问 通过一下方法绕过这堵墙,成功下载 GitHub 上的项目。过程非常简单…...

龙芯指令集LoongArch——学习笔记(1)
1 龙芯架构 PDF下载链接: https://www.loongson.cn/download/index 1.1 龙芯架构概述 龙芯架构具有 RISC 指令架构的典型特征。 它的指令长度固定且编码格式规整, 绝大多数指令只有两个源操作数和一个目的操作数, 采用 load/store 架构&…...
ubuntu 20.04 docker安装emqx 最新版本或指定版本
要在Ubuntu 20.04上使用Docker安装EMQX(EMQ X Broker)的4.4.3版本,您可以执行以下步骤: 1.更新系统包列表: sudo apt update2.安装Docker: sudo apt install docker.io3.启动Docker服务并设置其开机自启…...

软件测试/测试开发丨学会与 AI 对话,高效提升学习效率
点此获取更多相关资料 简介 ChatGPT 的主要优点之一是它能够理解和响应自然语言输入。在日常生活中,沟通本来就是很重要的一门课程,沟通的过程中表达越清晰,给到的信息越多,那么沟通就越顺畅。 和 ChatGPT 沟通也是同样的道理&…...

CEF内核和高级爬虫知识
(转)关于MFC中如何使用CEF内核(CEF初解析) Python GUI: cefpython3的简单分析和应用 cefpython3:一款强大的Python库 开始大多数抓取尝试可以从几乎一行代码开始: fun main() PulsarContexts.createSession().scrapeOutPages(&q…...

视频集中存储/云存储/磁盘阵列EasyCVR平台分组批量绑定/取消设备功能详解
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台视频能力丰富灵活,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理平台EasyCVR既具备传…...

科技成果鉴定测试报告一般包含哪些测试内容?
软件测评报告 一、科技成果评价是需要做第三方软件测评报告,一般是证明技术指标点是否完善,覆盖主要申报内容,应用软件项目科技成果鉴定测试内容: (一)是否完成合同或计划任务书要求的指标; …...

IDEA中的“Deployment“ 将项目直接部署到服务器上
ntelliJ IDEA中的"Deployment"工具栏是一个方便的工具,用于将你的项目直接部署到服务器上。这个工具栏提供了三种部署的方式: 1.Web Server在本地电脑上,并且服务器运行目录也在项目目录下。 2.Web Server在本地电脑上,…...

密室逃脱小游戏
欢迎来到程序小院 密室逃脱 玩法: 判断可生存的空间,鼠标点击屏幕进行人物左右移动,躲避闸道进行生存,每进行一次关卡都会有分数统计,赶紧去闯关吧^^。开始游戏https://www.ormcc.com/play/gameStart/176 html <c…...
【MyBatis】MyBatis项目结构的搭建
Mybatis项目的搭建 依赖 将打包方式添加为jar包 <groupId>com.qinghe.mybatis</groupId><artifactId>Mybatis_demo3</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging>添加如下依赖 <depen…...
Vant组件库入门知识
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎 📚系列专栏:Java全栈,…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...