微服务框架 SpringCloud微服务架构 26 数据聚合 26.5 多条件聚合
微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
SpringCloud微服务架构
文章目录
- 微服务框架
- SpringCloud微服务架构
- 26 数据聚合
- 26.5 多条件聚合
- 26.5.1 直接开干
26 数据聚合
26.5 多条件聚合
26.5.1 直接开干
案例:在IUserService中定义方法,实现对品牌、城市、星级的聚合
需求:搜索页面的品牌、城市等信息不应该是在页面写死,而是通过聚合索引库中的酒店数据得来的:
在IUserService中定义一个方法,实现对品牌、城市、星级的聚合,方法声明如下:
直接开干
package cn.itcast.hotel.service;import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.PageResult;
import cn.itcast.hotel.pojo.RequestParams;
import com.baomidou.mybatisplus.extension.service.IService;import java.util.List;
import java.util.Map;public interface IHotelService extends IService<Hotel> {PageResult search(RequestParams params);Map<String , List<String>> filters();
}
修改实现类,实现这个接口
package cn.itcast.hotel.service.impl;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.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
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.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilder;
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 org.springframework.util.CollectionUtils;import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
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 PageResult search(RequestParams params) {try {//1. 准备RequestSearchRequest request = new SearchRequest("hotel");//2. 准备DSL//2.1 关键字搜索querybuildBasicQuery(params, request);//2.2 分页Integer page = params.getPage();Integer size = params.getSize();request.source().from((page - 1) * size).size(size);//2.3 排序//2.3.1 地理位置排序String location = params.getLocation();System.out.println(location);if (location != null && !location.equals("")) {request.source().sort(SortBuilders.geoDistanceSort("location", new GeoPoint(location)).order(SortOrder.ASC).unit(DistanceUnit.KILOMETERS));}//2.3.2 sortBy排序String sortBy = params.getSortBy();System.out.println(sortBy);if (sortBy != null && !sortBy.equals("")){if (sortBy.equals("default")){;}if(sortBy.equals("score")){request.source().sort("score",SortOrder.DESC);}if (sortBy.equals("price")){request.source().sort("price",SortOrder.ASC);}}//3. 发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4. 解析响应return handleResponse(response);} catch (IOException e) {throw new RuntimeException(e);}}@Overridepublic Map<String, List<String>> filters() {try {//1. 准备RequestSearchRequest request = new SearchRequest("hotel");//2. 准备DSL//2.1 设置sizerequest.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();//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 static 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;}private static 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 static void buildBasicQuery(RequestParams params, SearchRequest request) {//1. 构建BooleanQueryBoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//关键字搜索String key = params.getKey();//健壮判断if (key == null || "".equals(key)) {boolQuery.must(QueryBuilders.matchAllQuery());} else {boolQuery.must(QueryBuilders.matchQuery("all", key));//3. 高亮控制request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));}//条件过滤//【城市】if (params.getCity() != null && !params.getCity().equals("")) {boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));}//【品牌】if (params.getBrand() != null && !params.getBrand().equals("")) {boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));}//【星级】if (params.getStarName() != null && !params.getStarName().equals("")) {boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));}//【价格】if (params.getMinPrice() != null && params.getMaxPrice() != null) {boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));}//2. 算分控制FunctionScoreQueryBuilder functionScoreQuery =QueryBuilders.functionScoreQuery(// 原始查询,相关性算分的查询boolQuery,//function score 的数组new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{//其中的一个function score 元素new FunctionScoreQueryBuilder.FilterFunctionBuilder(//过滤条件QueryBuilders.termQuery("isAD", true),//算分函数ScoreFunctionBuilders.weightFactorFunction(10))});request.source().query(functionScoreQuery);}private PageResult handleResponse(SearchResponse response) {//4. 解析响应SearchHits searchHits = response.getHits();//4.1 获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");//4.2 文档数组SearchHit[] hits = searchHits.getHits();System.out.println("====================>文档数组");System.out.println(hits);//4.3 遍历List<HotelDoc> hotels = new ArrayList<>();for (SearchHit hit : hits) {//获取文档sourceString json = hit.getSourceAsString();//反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);//获取高亮结果Map<String, HighlightField> highlightFields = hit.getHighlightFields();//健壮判断if (!CollectionUtils.isEmpty(highlightFields)){//根据字段名获取高亮结果HighlightField highlightField = highlightFields.get("name");//健壮判断if (highlightField != null) {//获取高亮值String name = highlightField.getFragments()[0].string();//覆盖非高亮结果hotelDoc.setName(name);}}//获取排序值Object[] sortValues = hit.getSortValues();if (sortValues.length > 0) {Object sortValue = sortValues[0];hotelDoc.setDistance(sortValue);}System.out.println(hotelDoc);hotels.add(hotelDoc);}//4.4 封装返回return new PageResult(total, hotels);}
}
OK,测试一下
package cn.itcast.hotel;import cn.itcast.hotel.service.IHotelService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;
import java.util.Map;@SpringBootTest
class HotelDemoApplicationTests {@Autowiredprivate IHotelService hotelService;@Testvoid contextLoads() {Map<String, List<String>> filters = hotelService.filters();System.out.println(filters);}}
直接运行
没毛病
微服务框架 SpringCloud微服务架构 26 数据聚合 26.5 多条件聚合相关推荐
- 微服务框架 SpringCloud微服务架构 27 自动补全 27.2 自定义分词器
微服务框架 [SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务] SpringCloud微服务 ...
- 微服务框架 SpringCloud微服务架构 25 黑马旅游案例 25.5 排序和搜索关键字高亮
微服务框架 [SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务] SpringCloud微服务 ...
- 微服务框架 SpringCloud微服务架构 25 黑马旅游案例 25.4 广告置顶
微服务框架 [SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务] SpringCloud微服务 ...
- 微服务框架 SpringCloud微服务架构 服务异步通讯 51 死信交换机 51.3 延迟队列 51.3.1 延迟队列 51.3.2 延迟队列插件
微服务框架 [SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务] 服务异步通讯 文章目录 微服 ...
- 微服务框架 SpringCloud微服务架构 分布式事务 38 动手实践 38.2 实现XA 模式
微服务框架 [SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务] 分布式事务 文章目录 微服务 ...
- 最新微服务框架SpringCloud Alibaba介绍,搭建
微服务和SpringCloud Alibaba详细介绍(一),手把手搭建微服务框架 PS:本博客是本人参照B站博主:JAVA阿伟如是说 的视频讲解手敲整理的笔记 跟着一起手动搭建的框架 供大家一起学习 ...
- 华为18级大牛倾情奉送:分布式服务框架和微服务设计原理实战文档,啃完发现涨薪如此简单
前言 分布式服务框架不仅仅包含核心的运行时类库,还包括服务划分原则.服务化最佳实践.服务治理.服务监控.服务开发框架等,它是一套完整的解决方案,用来协助应用做服务化改造,以及指导用户如何构建适合自己业 ...
- JavaEE 企业级分布式高级架构师(十三)微服务框架 SpringCloud (H 版)(1)
Spring Cloud学习笔记 Spring Cloud入门 分布式技术图谱 Spring Cloud简介 官网介绍 百度百科 总结 Spring Cloud的国内使用情况 Spring Cloud ...
- springcloud全局过滤_微服务技术SpringCloud 互联网网站架构演变过程
网站架构演变过程 传统架构 传统的SSH架构,分为三层架构 web控制层.业务逻辑层.数据库访问层. 传统架构也就是单点应用,就是大家在刚开始初学JavaEE技术的时候SSH架构或者SSM架构,业务没 ...
最新文章
- 【Codeforces】 2A - Winner (map)
- 解题报告:luogu P1688 新单词接龙问题【trie树、dfs、DP递推】
- vim 高级使用技巧第二篇
- elasticsearch完全匹配
- Android studio中git密码记住的问题
- spring boot分层_只需5分钟即可启动并运行分层架构:: Spring Boot第1部分
- 牛客网SQL篇刷题篇(32-37)
- Yii-模型- criteria查找数据库方法
- BZOJ 4155 Humble Captains
- elf 取路径_PatchELF 修改linux下elf文件library搜索路径
- shape context matlab,形状上下文(shape context)算法完全解读
- ICCV'21 Oral|拒绝调参,显著提点!检测分割任务的新损失函数RS Loss开源
- 通过开发对接淘宝联盟发单淘宝客优惠线报自动转链接社转发返利机器人球鞋搬砖
- matlab 液压控制系统设计,基于MATLAB的液压系统的设计与仿真
- 22考研各科标准答题卡(附高清PDF版)
- WZ安卓面试宝典App
- 31 家企业入选阿里云首期云原生加速器,共建云原生行业新生态
- writing science_Science子刊: 类配对分析法揭示孤独症患者肠道菌群解毒功能受损
- Google Play游戏服务入门
- 几个不错的extjs的blog