电商项目-基于ElasticSearch实现商品搜索功能(四)
一、 高亮显示
1.1 高亮分析
高亮显示是指根据商品关键字搜索商品的时候,显示的页面对关键字给定了特殊样式,让它显示更加突出,如商品搜索中,关键字变成了红色,其实就是给定了红色样式。
1.2 高亮搜索实现步骤解析
将之前的搜索换掉,换成高亮搜索,我们需要做3个步骤:
1.指定高亮域,也就是设置哪个域需要高亮显示设置高亮域的时候,需要指定前缀和后缀,也就是关键词用什么html标签包裹,再给该标签样式
2.高亮搜索实现
3.将非高亮数据替换成高亮数据
第1点,例如在百度中搜索数据的时候,会有2个地方高亮显示,分别是标题和描述,商城搜索的时候,只是商品名称高亮显示了。而高亮显示其实就是添加了样式,例如手机,而其中span开始标签可以称为前缀,span结束标签可以称为后缀。
第2点,高亮搜索使用ElasticsearchTemplate实现。
第3点,高亮搜索后,会搜出非高亮数据和高亮数据,高亮数据会加上第1点中的高亮样式,此时我们需要将非高亮数据换成高亮数据即可。例如非高亮:华为笔记本性能超强悍 高亮数据:华为<span style="color:red;"笔记本性能超强悍,将非高亮的换成高亮的,到页面就能显示样式了。
1.3 高亮代码实现
高亮代码实现:
代码如下:
@Override
public Map search(Map<String, String> searchMap) throws Exception {Map<String, Object> resultMap = new HashMap<>();
//有条件才查询Esif (null != searchMap) {//组合条件对象BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//0:关键词if (!StringUtils.isEmpty(searchMap.get("keywords"))) {boolQuery.must(QueryBuilders.matchQuery("name", searchMap.get("keywords")).operator(Operator.AND));}//1:条件 品牌if (!StringUtils.isEmpty(searchMap.get("brand"))) {boolQuery.filter(QueryBuilders.termQuery("brandName", searchMap.get("brand")));}
//2:条件 规格for (String key : searchMap.keySet()) {if (key.startsWith("spec_")) {String value = searchMap.get(key).replace("%2B", "+");boolQuery.filter(QueryBuilders.termQuery("specMap." + key.substring(5) + ".keyword",value));}}//3:条件 价格if (!StringUtils.isEmpty(searchMap.get("price"))) {String[] p = searchMap.get("price").split("-");boolQuery.filter(QueryBuilders.rangeQuery("price").gte(p[0]));if (p.length == 2) {boolQuery.filter(QueryBuilders.rangeQuery("price").lte(p[1]));}}
//4. 原生搜索实现类NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(boolQuery);
//5:高亮HighlightBuilder.Field field = new HighlightBuilder.Field("name").preTags("<span style='color:red'>").postTags("</span>");nativeSearchQueryBuilder.withHighlightFields(field);
//6. 品牌聚合(分组)查询String skuBrand = "skuBrand";nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(skuBrand).field("brandName"));
//7. 规格聚合(分组)查询String skuSpec = "skuSpec";nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(skuSpec).field("spec.keyword"));
//8: 排序if (!StringUtils.isEmpty(searchMap.get("sortField"))) {if ("ASC".equals(searchMap.get("sortRule"))) {nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.ASC));} else {
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.DESC));}
}
String pageNum = searchMap.get("pageNum");if (null == pageNum) {pageNum = "1";}//9: 分页nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(pageNum) - 1, Page.pageSize));
//10: 执行查询, 返回结果对象AggregatedPage<SkuInfo> aggregatedPage = esTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class, new SearchResultMapper() {@Overridepublic <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
List<T> list = new ArrayList<>();
SearchHits hits = searchResponse.getHits();if (null != hits) {for (SearchHit hit : hits) {SkuInfo skuInfo = JSON.parseObject(hit.getSourceAsString(), SkuInfo.class);
Map<String, HighlightField> highlightFields = hit.getHighlightFields();if (null != highlightFields && highlightFields.size() > 0) {skuInfo.setName(highlightFields.get("name").getFragments()[0].toString());}list.add((T) skuInfo);}}return new AggregatedPageImpl<T>(list, pageable, hits.getTotalHits(), searchResponse.getAggregations());}});
//11. 总条数resultMap.put("total", aggregatedPage.getTotalElements());//12. 总页数resultMap.put("totalPages", aggregatedPage.getTotalPages());//13. 查询结果集合resultMap.put("rows", aggregatedPage.getContent());
//14. 获取品牌聚合结果StringTerms brandTerms = (StringTerms) aggregatedPage.getAggregation(skuBrand);List<String> brandList = brandTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());resultMap.put("brandList", brandList);
//15. 获取规格聚合结果StringTerms specTerms = (StringTerms) aggregatedPage.getAggregation(skuSpec);List<String> specList = specTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());resultMap.put("specList", specList(specList));
//16. 返回当前页resultMap.put("pageNum", pageNum);
return resultMap;}
return null;
}
1.4 测试
测试搜索结果高亮显示
相关文章:
电商项目-基于ElasticSearch实现商品搜索功能(四)
一、 高亮显示 1.1 高亮分析 高亮显示是指根据商品关键字搜索商品的时候,显示的页面对关键字给定了特殊样式,让它显示更加突出,如商品搜索中,关键字变成了红色,其实就是给定了红色样式。 1.2 高亮搜索实现步骤解析 …...
TCP封装数据帧
void *send_data(void *arg) //这是一个发送数据的线程 {int sockfd init_tcp_cli("192.168.0.148",50000) //传ip和port,port 50000是因为大概前五万都被其它服务所占用,50000后是私人ipif(sockfd < 0){return NULL;}unsigned char …...
数据结构与算法之二叉树: LeetCode 515. 在每个树行中找最大值 (Ts版)
在每个树行中找最大值 https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/ 描述 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值 示例1 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9]示例2 输入: root [1,2,3]…...
百度视频搜索架构演进
导读 随着信息技术的迅猛发展,搜索引擎作为人们获取信息的主要途径,其背后的技术架构也在不断演进。本文详细阐述了近年来视频搜索排序框架的重大变革,特别是在大模型技术需求驱动下,如何从传统的多阶段级联框架逐步演变为更加高…...
构造函数的原型原型链
代码示例 // 定义一个构造函数 Test function Test() {this.name 张三 }; //向构造函数的原型添加一个属性 age18 Test.prototype.age 18;//使用构造函数 Test 来实例化一个新对象 const test new Test();//向 Object.prototype 添加了一个名为 sex 的属性,其值…...
nginx反向代理及负载均衡
华子目录 nginx反向代理功能http反向代理反向代理配置参数proxy_pass的注意事项案例:反向代理单台后端服务器案例:反向代理实现动静分离案例:反向代理的缓存功能非缓存场景下测压准备缓存缓存场景下测压验证缓存文件 反向代理负载均衡&#x…...
单片机实物成品-011 火灾监测
火灾监测(20个版本) 版本20: oled显示温湿度烟雾浓度火焰传感器天然气浓度窗户风扇水泵排气系统声光报警语音播报按键WIFI模块 ----------------------------------------------------------------------------- https://www.bilibili.com…...
使用 Docker 在 Alpine Linux 下部署 Caddy 服务器
简介 在现代 web 开发中,选择合适的 web 服务器至关重要。Caddy 是一个功能强大的现代化 HTTP/2 服务器,支持自动 HTTPS,配置简单,适合开发和生产环境。Docker 则为我们提供了一种轻量级的容器化技术,使得应用程序的部…...
每日十题八股-2025年1月12日
1.为什么四次挥手之后要等2MSL? 2.服务端出现大量的timewait有哪些原因? 3.TCP和UDP区别是什么? 4.TCP为什么可靠传输 5.怎么用udp实现http? 6.tcp粘包怎么解决? 7.TCP的拥塞控制介绍一下? 8.描述一下打开百度首页后发生的网络过…...
Python中定位包含特定文本信息的元素
目录 一、为什么需要定位包含文本信息的元素 二、使用Selenium定位包含文本的元素 1. 使用find_element_by_link_text 2. 使用find_element_by_partial_link_text 3. 使用XPath定位包含文本的元素 4. 使用CSS选择器定位包含文本的元素 三、使用BeautifulSoup定位包含文本…...
uniapp实现H5页面内容居中与两边留白,打造类似微信公众号阅读体验
在 UniApp 中,由于需要兼容多端应用,我们通常使用 rpx 作为尺寸单位。然而,在某些情况下,如需要实现内容居中且两边留白时,直接使用 rpx 可能会带来一些限制。这时,我们可以考虑使用 px 或 rem 等单位&…...
极品飞车6里的赛道简介
极品飞车里有很多赛道,赛道分为前向赛道Forward、后向赛道Backward。前向赛道Forward是从A点到B点;后向赛道Backward是前向赛道的逆过程,即从B点到A点。这里介绍极品飞车6的赛道长度、中英文名称翻译、难度等级。 序号赛道英文名赛道中文名总长(km)急弯难度等级1Alpine Trai…...
SAP推出云端ERP解决方案,加速零售行业数字化转型
2025年1月9日,SAP发布了一款专为零售行业设计的云端ERP行业解决方案——S/4HANA Cloud Public Edition,进一步推动企业向云端迁移。这款解决方案旨在集中运营数据,整合财务、采购和商品管理流程,以帮助零售企业优化运营效率。 核…...
Python爬虫进阶——案例:模拟bilibili登录)
主要内容:模拟bilibili账号密码登录,不要实现的的实现功能是单击登录按钮,切换登录方式, 输入账号和密码,然后完成图片点击验证,最后单击立即登录按钮。 1、第一步:通过selenium模块访问bilibi…...
什么是数据分析?
什么是数据分析? 数据分析(Data Analysis)是指通过对数据进行收集、整理、处理、建模和解读,以揭示数据中的有用信息、支持决策和解决实际问题的过程。它是一门将数据转化为知识的学科,广泛应用于商业、科学研究、医疗…...
基于springboot的课程作业管理系统源码(springboot+vue+mysql)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的课程作业管理系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 可以管理首页、个人中心…...
多线程之旅:属性及其基本操作
上次分享到了,多线程中是是如何创建的,那么接下来,小编继续分享下多线程的相关知识。 多线程中的一些基本属性。 基本属性 属性获取方法IDgetId()名称getName()状态getState()优先级getPriority()是否后台线程isDemo()是否存活isAlive()是…...
数据表中的数据插入、更新和删除
文章目录 一、表的插入二、更新表中的数据记录三、删除表中的数据记录 一、表的插入 插入数据记录是常见的数据操作,可以显示向表中增加的新的数据记录。在MySQL中可以通过“INSERT INTO”语句来实现插入数据记录,该SQL语句可以通过如下4种方式使用&…...
Q_OBJECT宏报错的问题
在Qt中继承QObject,并且加上Q_OBJECT宏,有时候会报错,比如我的错误: error: debug/httpmgr.o:httpmgr.cpp:(.rdata$.refptr._ZTV7HttpMgr[.refptr._ZTV7HttpMgr]0x0): undefined reference to vtable for HttpMgr 意思是没有虚…...
提升性能300ms:深入解析Spring多表联接查询优化与SQL调优实战
优化所需知识点(必须掌握) 索引篇 explain命令 重点:这是后续分析是否使用索引以及使用是否恰当的工具 作用:查看sql的执行计划,可以看sql语句是否使用了索引,索引的使用情况,以及sql的性能。 …...
tools.simonwillison.net图像处理工具集:从裁剪到优化的完整指南
tools.simonwillison.net图像处理工具集:从裁剪到优化的完整指南 【免费下载链接】tools Assorted useful tools, almost entirely generated using LLMs 项目地址: https://gitcode.com/gh_mirrors/tools23/tools tools.simonwillison.net图像处理工具集是一…...
从测速到配置:一套完整的cFosSpeed网络加速保姆级教程(适用于小白)
从零开始掌握cFosSpeed:网络加速全流程实战指南对于经常进行在线游戏、视频会议或大文件传输的用户来说,网络延迟和带宽利用率低下往往是影响体验的关键痛点。cFosSpeed作为一款专业的网络流量优化工具,能够显著改善这些问题,但许…...
第三幕 御酒掺土,江山为祭
金牌监制,您这一刀改得极其精准,直接把整部戏的格局从“江湖恩怨”拉升到了“家国博弈”的层面!确实,如果只谈慈悲,唐三藏只是个高僧;但如果加上李世民的重托和大唐的国运,他就是一个背负着沉重…...
孤舟笔记 互联网常用框架篇二 Dubbo服务请求失败怎么处理?集群容错策略你用过几种
文章目录先说结论Failover:换家店试试Failfast:不行就算了Failsafe:忘了这事Failback:回头再说Forking:同时点几家Broadcast:通知所有人怎么选择回答技巧与点评加分回答面试官点评个人网站分布式系统中&…...
什么情况下会核销贷款
贷款核销的核心前提是:贷款被认定为 “损失类” 且经 “穷尽追偿” 仍无法收回,银行按监管与会计规则从账面冲销,但债权不消灭、仍可追偿。一、核心认定条件(满足其一即可)破产 / 注销 / 吊销:借款人和担保…...
密码学入门:区块链中的密码学原理
密码学入门:区块链中的密码学原理 大家好,我是欧阳瑞(Rich Own)。今天想和大家聊聊密码学这个重要话题。作为一个Web3探索者,密码学是区块链的基础。今天就来分享一下区块链中常用的密码学原理。 为什么密码学很重要&a…...
失传34年的南极DOS游戏LAN - LOK重见天日,背后藏着怎样的历史?
LAN - LOK:失传34年的南极DOS破坏游戏这是一次对历史进行重构(或许还会进行现代化改造)的尝试。AlphaPixel常处理遗留代码库,接触到80年代和90年代用各种方言和语言编写、存储在难处理容器和介质中的代码。因保密协议,…...
2026年新能源人才全球本地化策略
导读:报告基于领英行业洞察,聚焦 2026 年全球新能源行业发展格局、中国企业出海现状、人才供需痛点及全球化人才本地化落地策略,为新能源企业海外人才招聘、培养与组织管理提供完整解决方案。关注公众号:【互联互通社区】…...
动物森友会岛屿设计终极指南:用Happy Island Designer打造梦想岛屿
动物森友会岛屿设计终极指南:用Happy Island Designer打造梦想岛屿 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)",是一个在线工具,它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会》(Anim…...
Safe Exam Browser 虚拟化检测绕过技术深度实践
Safe Exam Browser 虚拟化检测绕过技术深度实践 【免费下载链接】safe-exam-browser-bypass A VM and display detection bypass for SEB. 项目地址: https://gitcode.com/gh_mirrors/sa/safe-exam-browser-bypass 在现代教育技术领域,Safe Exam Browser&…...
