1. package cn.wangju.core.service;
  2.  
  3. import cn.wangju.core.pojo.item.Item;
  4. import cn.wangju.core.util.Constants;
  5. import com.alibaba.dubbo.config.annotation.Service;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.data.domain.Page;
  8. import org.springframework.data.domain.Sort;
  9. import org.springframework.data.redis.core.RedisTemplate;
  10. import org.springframework.data.solr.core.SolrTemplate;
  11. import org.springframework.data.solr.core.query.*;
  12. import org.springframework.data.solr.core.query.result.*;
  13.  
  14. import java.util.ArrayList;
  15. import java.util.HashMap;
  16. import java.util.List;
  17. import java.util.Map;
  18.  
  19. /**
  20. * @author wangju
  21. * @date 2019/11/21 19:20
  22. */
  23. @Service
  24. public class SearchItemServiceImpl implements SearchItemService{
  25. @Autowired
  26. private SolrTemplate solrTemplate;
  27.  
  28. @Autowired
  29. private RedisTemplate redisTemplate;
  30.  
  31. /* @Override
  32. public Map<String, Object> searchItem(Map searchMap) {
  33. // 获取查询的条件
  34. String keywords = (String)searchMap.get("keywords");
  35. //当前页
  36. Integer pageNo = (Integer) searchMap.get("pageNo");
  37. //每页查询多少条
  38. Integer pageSize = (Integer) searchMap.get("pageSize");
  39.  
  40. // 封装查询对象
  41. Query query = new SimpleQuery();
  42. Criteria criteria = new Criteria("item_keywords").is(keywords);
  43. //将查询的条件放入查询的对象
  44. query.addCriteria(criteria);
  45. if (pageNo!=null || pageNo<0){
  46. pageNo = 1;
  47. }
  48. pageNo = (pageNo-1)*pageSize;
  49. // 设置第几条开始
  50. query.setOffset(pageNo);
  51. // 每页查询多少条数据
  52. query.setRows(pageSize);
  53. // 去solr 查询并返回结果
  54. ScoredPage<Item> items = solrTemplate.queryForPage(query, Item.class);
  55. Map<String,Object> map = new HashMap<>();
  56. map.put("rows",items.getContent());
  57. map.put("totalPages",items.getTotalPages());
  58. map.put("total",items.getTotalElements());
  59.  
  60. return map;
  61. }*/
  62. @Override
  63. public Map<String, Object> searchItem(Map paramMap) {
  64. // 1 根据参数关键字 到solr 中查询(分页)过滤 总条数 总页数
  65. Map<String, Object> resultMap = highlightSearch(paramMap);
  66. //2 根据查询的参数 道solr中获取对应的分类结果 因为分类有重复 按分组的方式去重复
  67. List<String> groupCatgroupList = findGroupCatgroupList(paramMap);
  68. resultMap.put("categoryList",groupCatgroupList);
  69. // 3 判断paramMap传入的参数中是否有分类的名称
  70. String category = String.valueOf(paramMap.get("category"));
  71. if(category!=null&&!"".equals(category)){
  72. //5 如果有分类参数 则根据分类查询对应的品牌集合和规格集合
  73. Map specListAndBrandList = findSpecListAndBrandList(category);
  74. resultMap.putAll(specListAndBrandList);
  75. }else {
  76. //4 如果没有 根据第一个分类查询对应的商品集合
  77. Map specListAndBrandList = findSpecListAndBrandList(groupCatgroupList.get());
  78. resultMap.putAll(specListAndBrandList);
  79. }
  80.  
  81. return resultMap;
  82. }
  83. // 1 根据参数关键字 到solr 中查询(分页) 总条数 总页数
  84. private Map<String, Object> highlightSearch(Map paramMap){
  85. // 获取关键字
  86. String keywords = String.valueOf(paramMap.get("keywords"));
  87. if(keywords!=null){
  88. keywords = keywords.replaceAll(" ", "");
  89. }
  90. // 当前页码
  91. Integer pageNo = Integer.parseInt(String.valueOf(paramMap.get("pageNo")));
  92. // 每页的记录数
  93. Integer pageSize = Integer.parseInt(String.valueOf(paramMap.get("pageSize")));
  94. // 封装查询对象
  95. HighlightQuery query = new SimpleHighlightQuery();
  96. //查询的条件对象
  97. Criteria criteria = new Criteria("item_keywords").is(keywords);
  98. // 将查询条件放入对象中
  99. query.addCriteria(criteria);
  100. //计算从第几条开始查询
  101. if(pageNo==null||pageNo<=){
  102. pageNo=;
  103. }
  104. Integer start = (pageNo - ) * pageSize;
  105. // 设置从第几条记录查询
  106. query.setOffset(start);
  107. // 设置每页多少条
  108. query.setRows(pageSize);
  109.  
  110. //2按分类筛选
  111. if(!"".equals(paramMap.get("category"))){
  112. Criteria filterCriteria=new Criteria("item_category").is(paramMap.get("category"));
  113. FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
  114. query.addFilterQuery(filterQuery);
  115. }
  116. //3按品牌筛选
  117. if(!"".equals(paramMap.get("brand"))){
  118. Criteria filterCriteria=new Criteria("item_brand").is(paramMap.get("brand"));
  119. FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
  120. query.addFilterQuery(filterQuery);
  121. }
  122. //4过滤规格
  123. if(paramMap.get("spec")!=null){
  124. Map<String,String> specMap= (Map) paramMap.get("spec");
  125. for(String key:specMap.keySet() ){
  126. Criteria filterCriteria=new Criteria("item_spec_"+key).is( specMap.get(key) );
  127. FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
  128. query.addFilterQuery(filterQuery);
  129. }
  130. }
  131. //5价格的筛选
  132. String price = (String) paramMap.get("price");
  133. if (!price.equals("")){
  134. String[] split = price.split("-");
  135. if (!split[].equals("")){
  136. Criteria filterCriteria = new Criteria("item_price").greaterThanEqual(split[]);
  137. FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
  138. query.addFilterQuery(filterQuery);
  139. }
  140. if (!split[].equals("*")){
  141. Criteria filterCriteria = new Criteria("item_price").lessThanEqual(split[]);
  142. FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
  143. query.addFilterQuery(filterQuery);
  144. }
  145. }
  146. // 6价格的排序
  147. //排序的方式
  148. String sort = (String)paramMap.get("sort");
  149. String sortField = (String)paramMap.get("sortField");
  150. if (sort!=null && !sort.equals("")){
  151. if (sort.equals("ASC")){
  152. Sort sort1 = new Sort(Sort.Direction.ASC,"item_"+sortField);
  153. query.addSort(sort1);
  154. }
  155. if (sort.equals("DESC")){
  156. Sort sort1 = new Sort(Sort.Direction.DESC,"item_"+sortField);
  157. query.addSort(sort1);
  158. }
  159. }
  160.  
  161. //创建高亮显示对象
  162. HighlightOptions highlightOptions = new HighlightOptions();
  163. // 设置哪个域需要高亮显示
  164. highlightOptions.addField("item_title");
  165. // 高亮的前缀
  166. highlightOptions.setSimplePrefix("<em style='color:red'>");
  167. // 高亮的后缀
  168. highlightOptions.setSimplePostfix("</em>");
  169. // 将高亮假如到查询对象中
  170. query.setHighlightOptions(highlightOptions);
  171. // 查询并且返回结果
  172. HighlightPage<Item> items = solrTemplate.queryForHighlightPage(query, Item.class);
  173.  
  174. //获取带高亮的集合
  175. List<HighlightEntry<Item>> highlighted = items.getHighlighted();
  176. List<Item> itemList = new ArrayList<>();
  177. //遍历高亮集合
  178. for(HighlightEntry<Item> itemHighlightEntry:highlighted){
  179. Item item = itemHighlightEntry.getEntity();
  180. List<HighlightEntry.Highlight> highlights = itemHighlightEntry.getHighlights();
  181. if(highlights!=null&&highlights.size()>){
  182. // 获取高亮的标题集合
  183. List<String> highlightTitle = highlights.get().getSnipplets();
  184. if(highlightTitle!=null&&highlightTitle.size()>){
  185. // 获取高亮的标题
  186. String title = highlightTitle.get();
  187. item.setTitle(title);
  188. }
  189. }
  190. itemList.add(item);
  191. }
  192. Map<String, Object> resultMap = new HashMap<>();
  193. //查询到的结果集
  194. resultMap.put("rows",itemList);
  195. // 总页数
  196. resultMap.put("totalPages",items.getTotalPages());
  197. // 总条数
  198. resultMap.put("total",items.getTotalElements());
  199. return resultMap;
  200. }
  201. //2 根据查询的参数 道solr中获取对应的分类结果 因为分类有重复 按分组的方式去重复
  202. private List<String> findGroupCatgroupList(Map paramMap){
  203. List<String> resultList = new ArrayList<>();
  204. // 获取关键字
  205. String keywords = String.valueOf(paramMap.get("keywords"));
  206. if(keywords!=null){
  207. keywords = keywords.replaceAll(" ", "");
  208. }
  209. // 创建查询对象
  210. SimpleQuery query = new SimpleQuery();
  211. // 创建查询条件对象
  212. Criteria criteria = new Criteria("item_keywords").is(keywords);
  213. // 将查询的条件放入道查询对象中
  214. query.addCriteria(criteria);
  215.  
  216. //创建分组对象
  217. GroupOptions groupOptions = new GroupOptions();
  218. //设置根据分类域进行分组
  219. groupOptions.addGroupByField("item_category");
  220. // 将分组对象放入查询对象中
  221. query.setGroupOptions(groupOptions);
  222. // 使用分组查询 分类集合
  223. GroupPage<Item> items = solrTemplate.queryForGroupPage(query, Item.class);
  224. // 获得结果集合 分类域集合
  225. GroupResult<Item> item_category = items.getGroupResult("item_category");
  226. //获得分类域中的实体集合
  227. Page<GroupEntry<Item>> groupEntries = item_category.getGroupEntries();
  228. // 遍历实体集合 得到实体对象
  229. for(GroupEntry<Item> groupEntry:groupEntries){
  230. String groupCategory = groupEntry.getGroupValue();
  231. // 组装到集合中
  232. resultList.add(groupCategory);
  233. }
  234.  
  235. return resultList;
  236.  
  237. }
  238. //4 根据分类名称查询对应品牌集合和规格集合
  239. private Map findSpecListAndBrandList(String categoryName){
  240. //a 根据分类名称到redis中查询对应的模板id
  241. Long templateId = (Long)redisTemplate.boundHashOps(Constants.CATEGORY_LIST_REDIS).get(categoryName);
  242. //b根据模板id 去redis中查询对应的品牌集合
  243. List<Map> brandList = (List<Map>)redisTemplate.boundHashOps(Constants.BRAND_LIST_REDIS).get(templateId);
  244. //b根据模板id 去redis中查询对应的规格集合
  245. List<Map> specList =(List<Map>) redisTemplate.boundHashOps(Constants.SPEC_LIST_REDIS).get(templateId);
  246. //a 将品牌集合和规格集合封装到Map中 返回
  247. Map resultMap = new HashMap();
  248. resultMap.put("brandList",brandList);
  249. resultMap.put("specList",specList);
  250. return resultMap;
  251.  
  252. }
  253. }

电商项目搜寻功能(分页,高亮,solr,规格过滤,价格的排序)的更多相关文章

  1. Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构

    Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...

  2. python-django电商项目-需求分析架构设计数据库设计_20191115

    python-django电商项目需求分析 1.用户模块 1)注册页 注册时校验用户名是否已被注册. 完成用户信息的注册. 给用户的注册邮箱发送邮件,用户点击邮件中的激活链接完成用户账户的激活. 2) ...

  3. Spark大型电商项目实战-及其改良之番外(1)-将spark前端页面效果高效拷贝至博客

    Spark大型电商项目实战-及其改良这个系列的时间轴展示图一直在变....1-3篇是用图直接表示时间轴,用一段简陋的html代码表示时间表.第4篇开始才是用比较完整的前端效果,能移动.缩放时间轴,鼠标 ...

  4. C#大型电商项目优化(二)——嫌弃EF与抛弃EF

    上一篇博文中讲述了使用EF开发电商项目的代码基础篇,提到EF后,一语激起千层浪.不少园友纷纷表示:EF不适合增长速度飞快的互联网项目,EF只适合企业级应用等等. 也有部分高手提到了分布式,确实,性能优 ...

  5. C# 大型电商项目性能优化(一)

    经过几个月的忙碌,我厂最近的电商平台项目终于上线,期间遇到的问题以及解决方案,也可以拿来和大家多做交流了. 我厂的项目大多采用C#.net,使用逐渐发展并流行起来的EF(Entity Framewor ...

  6. Mall电商项目总结(一)——项目概述

    项目概述 此电商项目为本人学习项目,后端 使用nginx实现负载均衡转发请求到多台tomcat服务器,使用多台 redis服务器分布式 缓存用户登录信息. 项目已经部署到阿里云服务器,从阿里云linu ...

  7. 常见电商项目的数据库表设计(MySQL版)

    转自:https://cloud.tencent.com/developer/article/1164332 简介: 目的: 电商常用功能模块的数据库设计 常见问题的数据库解决方案 环境: MySQL ...

  8. Spring Boot微服务电商项目开发实战 --- 基础配置及搭建

    根据SpringBoot实现分布式微服务项目近两年的开发经验,今天决定开始做SpringBoot实现分布式微服务项目的系列文章,帮助其他正在使用或计划使用SringBoot开发的小伙伴们.本次系列文章 ...

  9. web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 ☝☝☝

    web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程    web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 学习 ...

随机推荐

  1. oracle trunc 日期 数字 的使用例子

    /**************日期********************/1.select trunc(sysdate) from dual --2013-01-06 今天的日期为2013-01-0 ...

  2. 解决HttpServletRequest的输入流只能读取一次的问题

    背景 通常对安全性有要求的接口都会对请求参数做一些签名验证,而我们一般会把验签的逻辑统一放到过滤器或拦截器里,这样就不用每个接口都去重复编写验签的逻辑. 在一个项目中会有很多的接口,而不同的接口可能接 ...

  3. Elastic:如何在一个机器上同时模拟多个node

    Elastic:如何在一个机器上同时模拟多个node /bin/elasticsearch -E node.name=node1 -E cluster.name=my-application -E p ...

  4. 二叉查找树的实现与讲解(C++)

    注:这篇文章源于:https://mp.csdn.net/postedit/99710904, 无需怀疑抄袭,同一个作者,这是我在博客园的账号. 在二叉树中,有两种非常重要的条件,分别是两类数据结构的 ...

  5. 使用c#创建Excel 2013外接程序

    心好累,印象笔记国内版和国际版账号还不能通用,在国内版写了一个没法创建共享链接(只有共享给XXemail),于是又写了一遍到国际版上(因为图片无法复制,又copy了一遍图片),现在copy到博客园,图 ...

  6. 帝国CMS标签【操作类型】说明详解

    看标签的参数时候,一般最后一个参数是操作类型说明,可是后面写的是:"操作类型说明 具体看操作类型说明", 这个操作类型说明在什么地方看啊 操作类型 说明 操作类型 说明 0 各栏目 ...

  7. python+java蓝桥杯ACM日常算法题训练(一)10基础题

    目录 1.简单的a+b 2.第一个HelloWorld程序! 3.三个数最大值 4.密码破译 5.母牛的故事 6.7.8.9.10 @(这里写自定义目录标题) 算法题训练网站:http://www.d ...

  8. Android 蓝牙开发(1)

    普通蓝牙设备官方文档 Android 平台包含蓝牙网络堆栈支持,凭借此支持,设备能以无线方式与其他蓝牙设备交换数据.应用框架提供了通过 Android Bluetooth API 访问蓝牙功能的途径. ...

  9. 个人项目-WC.exe (Java实现)

    一.Github项目地址:https://github.com/blanche789/wordCount/tree/master/src/main/java/com/blanche 二.PSP表格 P ...

  10. ubuntu 改键

    参考: https://www.jianshu.com/p/9411ee427cfd https://www.cnblogs.com/zhengchl/archive/2012/08/25/26557 ...