package com.pinyougou.search.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;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.Criteria;
import org.springframework.data.solr.core.query.FilterQuery;
import org.springframework.data.solr.core.query.GroupOptions;
import org.springframework.data.solr.core.query.HighlightOptions;
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleFacetQuery;
import org.springframework.data.solr.core.query.SimpleFilterQuery;
import org.springframework.data.solr.core.query.SimpleHighlightQuery;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.GroupEntry;
import org.springframework.data.solr.core.query.result.GroupPage;
import org.springframework.data.solr.core.query.result.GroupResult;
import org.springframework.data.solr.core.query.result.HighlightEntry;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.data.solr.core.query.result.ScoredPage;import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.search.service.ItemSearchService;/**
* 搜索serviceimpl
*
* @author Administrator
*
*/
@SuppressWarnings("all")
@Service(timeout = 10000)
public class ItemSearchServiceImpl implements ItemSearchService { @Autowired
private SolrTemplate solrTemplate; /**
* 搜索
*/
@Override
public Map<String, Object> search(Map searchMap) { Map<String, Object> map = new HashMap<>();
Query query = new SimpleQuery();
Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
query.addCriteria(criteria);
ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
map.put("rows", page.getContent()); return map;
} /**
* 搜索高亮显示
*
* @param searchMap
* @return
*/
@Override
public Map<String, Object> searchHighlight(Map searchMap) {
Map<String, Object> map = new HashMap<>();
map.putAll(searchMap(searchMap));
List categoryList = searchCategoryList(searchMap);
map.put("categoryList", categoryList); // 查看是否传入了商品分类
String category = (String) searchMap.get("category");
if (category != "") {// 如果有商品分类(注意:商品分类只能选一个),那就按照商品分类返回规格和品牌
map.putAll(searchBrandAndSpecList(category));
} else {
if (categoryList.size() > 0) {
map.putAll(searchBrandAndSpecList((String) categoryList.get(0)));
}
} return map;
} /**
* 返回值也可以是List,Map更易于扩展
*
* @param searchMap
* @return
*/
private Map searchMap(Map searchMap) {
Map<String, Object> map = new HashMap<>();
// 高亮显示设置
HighlightQuery query = new SimpleHighlightQuery();
HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");// 设置高亮字段
highlightOptions.setSimplePrefix("<em style='color:red'>");// 设置高亮前缀
highlightOptions.setSimplePostfix("</em>");// 设置高亮后缀
query.setHighlightOptions(highlightOptions);// 设置高亮选项 // 1、按照关键字查询(关键字有可能被用户在中间加入空格,所以要去空格)
String keywords = (String) searchMap.get("keywords");
searchMap.put("keywords", keywords.replace(" ", ""));//取出所有空格
Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
query.addCriteria(criteria); // 2、按照商品分类查询
if (!"".equals(searchMap.get("category"))) {
Criteria filterCriteria = new Criteria("item_category").is(searchMap.get("category"));
FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
} // 3、按照品牌查询
if (!"".equals(searchMap.get("brand"))) {
Criteria filterCriteria = new Criteria("item_brand").is(searchMap.get("brand"));
FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
} // 4、按照规格查询
if (searchMap.get("spec") != null) {
Map<String, String> specMap = (Map) searchMap.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、按照价格区间查询
if (!"".equals(searchMap.get("price"))) { String[] price =((String) searchMap.get("price")).split("-");
if(!price[0].equals("0")){//最低价格不是0,最低价格就是price[0]
Criteria filterCriteria=new Criteria("item_price").greaterThanEqual(price[0]);
FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
} if(!price[1].equals("*")){//最高价格不是*,最高价格就是price[1]
Criteria filterCriteria=new Criteria("item_price").lessThanEqual(price[1]);
FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
query.addFilterQuery(filterQuery);
} }
// 6、分页查询
Integer pageNo = (Integer) searchMap.get("pageNo");//获取前端传入的查询第几页的页码
if(pageNo == null){//如果没有传入值,默认为1
pageNo = 1;
}
Integer pageSize = (Integer) searchMap.get("pageSize");//每页查询多少条
if(pageSize == null){//如果没有传入值,默认为20
pageSize = 20;
}
query.setOffset((pageNo-1)*pageSize);//从第几条记录查询
query.setRows(pageSize); //7、按照升降序条件查询
String sortValue = (String) searchMap.get("sort");
String sortField = (String) searchMap.get("sortField"); if(sortField != null && !sortField.equals("")){//需要升降序
if(sortValue.equals("ASC")){//升序
Sort sort = new Sort(Sort.Direction.ASC, "item_"+sortField);
query.addSort(sort);
} if(sortValue.equals("DESC")){//降序
Sort sort = new Sort(Sort.Direction.DESC, "item_"+sortField);
query.addSort(sort);
} }
// 根据条件查询,返回高亮显示结果
HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class); // 高亮显示获取结果
for (HighlightEntry<TbItem> h : page.getHighlighted()) {// 循环高亮入口集合
TbItem item = h.getEntity();
if (h.getHighlights().size() > 0 && h.getHighlights().get(0).getSnipplets().size() > 0) {
item.setTitle(h.getHighlights().get(0).getSnipplets().get(0));// 设置高亮显示结果。因为只有一个高亮域“.addField("item_title")”,所以不需要遍历,直接取第一个
}
} map.put("rows", page.getContent());
map.put("totalPages", page.getTotalPages());//返回总页数
map.put("total", page.getTotalElements());//返回总记录数
return map;
} /**
* 查询分类列表
*
* @param searchMap
* @return
*/
private List searchCategoryList(Map searchMap) { List<String> list = new ArrayList();
Query query = new SimpleQuery();
// 按照关键字查询
Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
query.addCriteria(criteria); // 设置分组选项
GroupOptions groupOptions = new GroupOptions().addGroupByField("item_category");
query.setGroupOptions(groupOptions); // 得到分组页
GroupPage<TbItem> page = solrTemplate.queryForGroupPage(query, TbItem.class); // 根据列得到分组结果集(这个域必须要是上面关键字查询集合中的一个,应为上面有可能有多个,这里是分开查询的,一个字段对应一个解决)
GroupResult<TbItem> groupResult = page.getGroupResult("item_category"); // 得到分页结果入口页
Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries(); // 得到分组入口集合
List<GroupEntry<TbItem>> content = groupEntries.getContent(); for (GroupEntry<TbItem> entry : content) {
list.add(entry.getGroupValue());// 将分组结果的名称分装到返回值中
}
return list;
} @Autowired
private RedisTemplate redisTemplate; /**
* 查询品牌和规格列表(从缓存中获取数据)
*
* @param category
* @return
*/
private Map searchBrandAndSpecList(String category) { Map map = new HashMap();
// 1、先从Redis中根据商品分类名称获取模版ID
Long templateId = (Long) redisTemplate.boundHashOps("itemCat").get(category); if (templateId != null) {
// 2、根据模版ID获取品牌列表
List brandList = (List) redisTemplate.boundHashOps("brandList").get(templateId);
map.put("brandList", brandList); // 3、根据模版ID获取规格列表
List specList = (List) redisTemplate.boundHashOps("specList").get(templateId);
map.put("specList", specList);
} return map;
}}
Solr实现商城搜索高亮显示
原创
©著作权归作者所有:来自51CTO博客作者光辉岁月松的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:linux下eclipse安装
下一篇:解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variabl
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Vue3.0中使用 highlight 实现代码高亮
Vue3.0中使用 highlight 实现代码高亮
编写代码 App css vue -
spring data solr实现关键字搜索+高亮显示+分组查询
、.springframe...
spring data solr solr 高亮 spring -
uniapp 搜索关键字高亮显示实现
其实是就是个正则表达式啊,主要还是得看后端返回的是什么数据,你才可以根据后端去更改即可。 显示:
html 数据 javascript -
JS实现HTM搜索关键词高亮显示
如何利用JS实现HTML搜索关键词高亮显示呢?目录一、程序案例代码二、程序运行效果一、程序案例代码<!DOCTYPE html>
javascript webview elementui html 搜索