电商项目搜寻功能(分页,高亮,solr,规格过滤,价格的排序)
package cn.wangju.core.service; import cn.wangju.core.pojo.item.Item;
import cn.wangju.core.util.Constants;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* @author wangju
* @date 2019/11/21 19:20
*/
@Service
public class SearchItemServiceImpl implements SearchItemService{
@Autowired
private SolrTemplate solrTemplate; @Autowired
private RedisTemplate redisTemplate; /* @Override
public Map<String, Object> searchItem(Map searchMap) {
// 获取查询的条件
String keywords = (String)searchMap.get("keywords");
//当前页
Integer pageNo = (Integer) searchMap.get("pageNo");
//每页查询多少条
Integer pageSize = (Integer) searchMap.get("pageSize"); // 封装查询对象
Query query = new SimpleQuery();
Criteria criteria = new Criteria("item_keywords").is(keywords);
//将查询的条件放入查询的对象
query.addCriteria(criteria);
if (pageNo!=null || pageNo<0){
pageNo = 1;
}
pageNo = (pageNo-1)*pageSize;
// 设置第几条开始
query.setOffset(pageNo);
// 每页查询多少条数据
query.setRows(pageSize);
// 去solr 查询并返回结果
ScoredPage<Item> items = solrTemplate.queryForPage(query, Item.class);
Map<String,Object> map = new HashMap<>();
map.put("rows",items.getContent());
map.put("totalPages",items.getTotalPages());
map.put("total",items.getTotalElements()); return map;
}*/
@Override
public Map<String, Object> searchItem(Map paramMap) {
// 1 根据参数关键字 到solr 中查询(分页)过滤 总条数 总页数
Map<String, Object> resultMap = highlightSearch(paramMap);
//2 根据查询的参数 道solr中获取对应的分类结果 因为分类有重复 按分组的方式去重复
List<String> groupCatgroupList = findGroupCatgroupList(paramMap);
resultMap.put("categoryList",groupCatgroupList);
// 3 判断paramMap传入的参数中是否有分类的名称
String category = String.valueOf(paramMap.get("category"));
if(category!=null&&!"".equals(category)){
//5 如果有分类参数 则根据分类查询对应的品牌集合和规格集合
Map specListAndBrandList = findSpecListAndBrandList(category);
resultMap.putAll(specListAndBrandList);
}else {
//4 如果没有 根据第一个分类查询对应的商品集合
Map specListAndBrandList = findSpecListAndBrandList(groupCatgroupList.get());
resultMap.putAll(specListAndBrandList);
} return resultMap;
}
// 1 根据参数关键字 到solr 中查询(分页) 总条数 总页数
private Map<String, Object> highlightSearch(Map paramMap){
// 获取关键字
String keywords = String.valueOf(paramMap.get("keywords"));
if(keywords!=null){
keywords = keywords.replaceAll(" ", "");
}
// 当前页码
Integer pageNo = Integer.parseInt(String.valueOf(paramMap.get("pageNo")));
// 每页的记录数
Integer pageSize = Integer.parseInt(String.valueOf(paramMap.get("pageSize")));
// 封装查询对象
HighlightQuery query = new SimpleHighlightQuery();
//查询的条件对象
Criteria criteria = new Criteria("item_keywords").is(keywords);
// 将查询条件放入对象中
query.addCriteria(criteria);
//计算从第几条开始查询
if(pageNo==null||pageNo<=){
pageNo=;
}
Integer start = (pageNo - ) * pageSize;
// 设置从第几条记录查询
query.setOffset(start);
// 设置每页多少条
query.setRows(pageSize); //2按分类筛选
if(!"".equals(paramMap.get("category"))){
Criteria filterCriteria=new Criteria("item_category").is(paramMap.get("category"));
FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
}
//3按品牌筛选
if(!"".equals(paramMap.get("brand"))){
Criteria filterCriteria=new Criteria("item_brand").is(paramMap.get("brand"));
FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
}
//4过滤规格
if(paramMap.get("spec")!=null){
Map<String,String> specMap= (Map) paramMap.get("spec");
for(String key:specMap.keySet() ){
Criteria filterCriteria=new Criteria("item_spec_"+key).is( specMap.get(key) );
FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
}
}
//5价格的筛选
String price = (String) paramMap.get("price");
if (!price.equals("")){
String[] split = price.split("-");
if (!split[].equals("")){
Criteria filterCriteria = new Criteria("item_price").greaterThanEqual(split[]);
FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
}
if (!split[].equals("*")){
Criteria filterCriteria = new Criteria("item_price").lessThanEqual(split[]);
FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
}
}
// 6价格的排序
//排序的方式
String sort = (String)paramMap.get("sort");
String sortField = (String)paramMap.get("sortField");
if (sort!=null && !sort.equals("")){
if (sort.equals("ASC")){
Sort sort1 = new Sort(Sort.Direction.ASC,"item_"+sortField);
query.addSort(sort1);
}
if (sort.equals("DESC")){
Sort sort1 = new Sort(Sort.Direction.DESC,"item_"+sortField);
query.addSort(sort1);
}
} //创建高亮显示对象
HighlightOptions highlightOptions = new HighlightOptions();
// 设置哪个域需要高亮显示
highlightOptions.addField("item_title");
// 高亮的前缀
highlightOptions.setSimplePrefix("<em style='color:red'>");
// 高亮的后缀
highlightOptions.setSimplePostfix("</em>");
// 将高亮假如到查询对象中
query.setHighlightOptions(highlightOptions);
// 查询并且返回结果
HighlightPage<Item> items = solrTemplate.queryForHighlightPage(query, Item.class); //获取带高亮的集合
List<HighlightEntry<Item>> highlighted = items.getHighlighted();
List<Item> itemList = new ArrayList<>();
//遍历高亮集合
for(HighlightEntry<Item> itemHighlightEntry:highlighted){
Item item = itemHighlightEntry.getEntity();
List<HighlightEntry.Highlight> highlights = itemHighlightEntry.getHighlights();
if(highlights!=null&&highlights.size()>){
// 获取高亮的标题集合
List<String> highlightTitle = highlights.get().getSnipplets();
if(highlightTitle!=null&&highlightTitle.size()>){
// 获取高亮的标题
String title = highlightTitle.get();
item.setTitle(title);
}
}
itemList.add(item);
}
Map<String, Object> resultMap = new HashMap<>();
//查询到的结果集
resultMap.put("rows",itemList);
// 总页数
resultMap.put("totalPages",items.getTotalPages());
// 总条数
resultMap.put("total",items.getTotalElements());
return resultMap;
}
//2 根据查询的参数 道solr中获取对应的分类结果 因为分类有重复 按分组的方式去重复
private List<String> findGroupCatgroupList(Map paramMap){
List<String> resultList = new ArrayList<>();
// 获取关键字
String keywords = String.valueOf(paramMap.get("keywords"));
if(keywords!=null){
keywords = keywords.replaceAll(" ", "");
}
// 创建查询对象
SimpleQuery query = new SimpleQuery();
// 创建查询条件对象
Criteria criteria = new Criteria("item_keywords").is(keywords);
// 将查询的条件放入道查询对象中
query.addCriteria(criteria); //创建分组对象
GroupOptions groupOptions = new GroupOptions();
//设置根据分类域进行分组
groupOptions.addGroupByField("item_category");
// 将分组对象放入查询对象中
query.setGroupOptions(groupOptions);
// 使用分组查询 分类集合
GroupPage<Item> items = solrTemplate.queryForGroupPage(query, Item.class);
// 获得结果集合 分类域集合
GroupResult<Item> item_category = items.getGroupResult("item_category");
//获得分类域中的实体集合
Page<GroupEntry<Item>> groupEntries = item_category.getGroupEntries();
// 遍历实体集合 得到实体对象
for(GroupEntry<Item> groupEntry:groupEntries){
String groupCategory = groupEntry.getGroupValue();
// 组装到集合中
resultList.add(groupCategory);
} return resultList; }
//4 根据分类名称查询对应品牌集合和规格集合
private Map findSpecListAndBrandList(String categoryName){
//a 根据分类名称到redis中查询对应的模板id
Long templateId = (Long)redisTemplate.boundHashOps(Constants.CATEGORY_LIST_REDIS).get(categoryName);
//b根据模板id 去redis中查询对应的品牌集合
List<Map> brandList = (List<Map>)redisTemplate.boundHashOps(Constants.BRAND_LIST_REDIS).get(templateId);
//b根据模板id 去redis中查询对应的规格集合
List<Map> specList =(List<Map>) redisTemplate.boundHashOps(Constants.SPEC_LIST_REDIS).get(templateId);
//a 将品牌集合和规格集合封装到Map中 返回
Map resultMap = new HashMap();
resultMap.put("brandList",brandList);
resultMap.put("specList",specList);
return resultMap; }
}
电商项目搜寻功能(分页,高亮,solr,规格过滤,价格的排序)的更多相关文章
- Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构
Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...
- python-django电商项目-需求分析架构设计数据库设计_20191115
python-django电商项目需求分析 1.用户模块 1)注册页 注册时校验用户名是否已被注册. 完成用户信息的注册. 给用户的注册邮箱发送邮件,用户点击邮件中的激活链接完成用户账户的激活. 2) ...
- Spark大型电商项目实战-及其改良之番外(1)-将spark前端页面效果高效拷贝至博客
Spark大型电商项目实战-及其改良这个系列的时间轴展示图一直在变....1-3篇是用图直接表示时间轴,用一段简陋的html代码表示时间表.第4篇开始才是用比较完整的前端效果,能移动.缩放时间轴,鼠标 ...
- C#大型电商项目优化(二)——嫌弃EF与抛弃EF
上一篇博文中讲述了使用EF开发电商项目的代码基础篇,提到EF后,一语激起千层浪.不少园友纷纷表示:EF不适合增长速度飞快的互联网项目,EF只适合企业级应用等等. 也有部分高手提到了分布式,确实,性能优 ...
- C# 大型电商项目性能优化(一)
经过几个月的忙碌,我厂最近的电商平台项目终于上线,期间遇到的问题以及解决方案,也可以拿来和大家多做交流了. 我厂的项目大多采用C#.net,使用逐渐发展并流行起来的EF(Entity Framewor ...
- Mall电商项目总结(一)——项目概述
项目概述 此电商项目为本人学习项目,后端 使用nginx实现负载均衡转发请求到多台tomcat服务器,使用多台 redis服务器分布式 缓存用户登录信息. 项目已经部署到阿里云服务器,从阿里云linu ...
- 常见电商项目的数据库表设计(MySQL版)
转自:https://cloud.tencent.com/developer/article/1164332 简介: 目的: 电商常用功能模块的数据库设计 常见问题的数据库解决方案 环境: MySQL ...
- Spring Boot微服务电商项目开发实战 --- 基础配置及搭建
根据SpringBoot实现分布式微服务项目近两年的开发经验,今天决定开始做SpringBoot实现分布式微服务项目的系列文章,帮助其他正在使用或计划使用SringBoot开发的小伙伴们.本次系列文章 ...
- web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 ☝☝☝
web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 web前端Vue+Django rest framework 框架 生鲜电商项目实战视频教程 学习 ...
随机推荐
- spring的事件
理论 异步的实现方式可以使用事件,或者异步执行: spring中自带了事件的支持,核心是ApplicationEventPublisher; 事件包括三个要点: 事件的定义: 事件监听的定义: 发布事 ...
- clientHeight—scrollHeight—offsetHeight三者的区别
clientHeight,scrollHeight,offsetHeight 这三个dom属性有时让人觉得相似但又不相似 以前对它们的理解也有一些模糊,现在总结一下,方便以后复习 clientHeig ...
- DOS命令行操作MySQL常用命令
平时用可视化界面用惯了,如果紧急排查问题,没有安装可视化工具的话,只能通过命令来看了. 以备不时之需,我们要熟悉一下命令行操作MySQL. 打开DOS命令窗口:WIN + R 输入cmd,回车 然后输 ...
- jieba 分词使用入门
1. 介绍 JIEBA 是目前最好的 Python 中文分词组件,它主要有以下 3 种特性: 支持 3 种分词模式:精确模式.全模式.搜索引擎模式 支持繁体分词 支持自定义词典 import jieb ...
- ASP.NET Core快速入门--学习笔记系列文章索引目录
课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 抓住国庆假期的尾巴完成了此系列课程的学习笔记输出! ASP.NET Core快 ...
- Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之三 || Swagger的使用 3.1
本文梯子 本文3.0版本文章 常见问题 1.Bug调试 2.经常有小伙伴遇到这个错误 3.路由重载 一.为什么使用Swagger 二.配置Swagger服务 1.引用Nuget包 2.配置服务 3.启 ...
- java基础(26):Thread、线程创建、线程池
1. 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并 ...
- java基础(23):字节流、字符流
1. 字节流 在前面的学习过程中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现在我们就要开始给文件中写数据,或者读取文件中的数据. 1.1 字节输出流OutputStream Out ...
- java核心技术第五篇之事务和MVC模式
第一部分:事务1.事务的简介: 1.1 在一组操作中(比如增加操作,修改操作),只有增加和修改操作都成功之后,这两个操作才能真正的成功. ,如果这两个操作中,有一个失败了,这两个操作都失败了. 1.2 ...
- log4cxx日志库在Windows+VS2017上的编译使用
项目中用到了log4cxx,但是Debug版本运行时老是提示找不到Properities::setProperty?怀疑是提供的库有问题,所以尝试源码来重新编译一下.log4cxx官方主页:https ...