solr高亮显示

package com.pinyougou.search.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.search.service.ItemSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
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;

@Service(timeout = 5000)
public class ItemSearchServiceImpl implements ItemSearchService {

	@Autowired
	private SolrTemplate solrTemplate;

	@Override
	public Map<String, Object> search(Map searchMap) {

		//装在搜索结果的map对象
		Map<String, Object> map = new HashMap<>();

		/*//从solr服务器上搜索数据
		Query query = new SimpleQuery("*:*");
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
		query.addCriteria(criteria);

		//从solr搜索回来的数据只有部分字段,所以只能填充TbItem的部分字段,未填充的就是null
		ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);*/


		//1、获取高亮的商品列表
		map.putAll(searchList(searchMap));

		2、分组查询  关键词所属的商品分类列表
		List<String> categoryList = searchCategoryList(searchMap);
		map.put("categoryList", categoryList);


		//3、根据分类,查询品牌和规格列表
		// ,默认显示第一个分类下面的品牌和规格

		if(categoryList.size()>0){
			//前端只输入了关键字,需要后端返回关键字所属的分类列表,默认显示第一个分类下的品牌和规格列表
			map.putAll(searchBrandAndSpecList(categoryList.get(0)));
		}

		return map;
	}



	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 根据分类名在redis中查找对应的品牌列表和规格列表
	 * @param category
	 * @return
	 */
	private Map searchBrandAndSpecList(String category) {

		//已知分类名称,搜索对应的品牌和规格,用的是SpringdataRedis存储的
		Map map = new HashMap();
		//1.根据商品分类名称得到模板ID	(这里的数据是在运营商管理时加入缓存的)
		Long templateId =(Long) redisTemplate.boundHashOps("itemCat").get(category);
		if(templateId!=null){
			//根据模板id,查找对应的品牌列表
			List brandList = (List)redisTemplate.boundHashOps("brandList").get(templateId);
			System.out.println("品牌列表的条数为:"+brandList.size());
			//返回值添加品牌列表
			map.put("brandList", brandList);

			//根据模板id,查找对应的规格选项,对应的是`tb_type_template`这个表
			List specList = (List)redisTemplate.boundHashOps("specList").get(templateId);
			System.out.println("规格列表的条数为:"+specList.size());
			map.put("specList", specList);
		}
		return map;


	}

	/**
	 * 设置高亮
	 * @param searchMap
	 * @return
	 */
	private Map searchList(Map searchMap) {
		Map map = new HashMap();
		HighlightQuery query = new SimpleHighlightQuery();
		HighlightOptions highlightOptions = new HighlightOptions();
		//设置需要高亮的域(字段)
		highlightOptions.addField("item_title");
		//设置高亮的前缀
		highlightOptions.setSimplePrefix("<em style='color:red'>");
		//设置高亮的后缀
		highlightOptions.setSimplePostfix("</em>");
		//将高亮的选项的设置装入query对象
		query.setHighlightOptions(highlightOptions);


		//1.1按照关键字查询所有符合条件的商品对象
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
		query.addCriteria(criteria);


		//1.2 按商品分类过滤
		//如果用户选择了分类
		if(!"".equals(searchMap.get("category"))  )	{
			FilterQuery filterQuery=new SimpleFilterQuery();
			Criteria filterCriteria=new Criteria("item_category").is(searchMap.get("category"));
			filterQuery.addCriteria(filterCriteria);
			query.addFilterQuery(filterQuery);
		}

		//1.3 按品牌过滤
		//如果用户选择了品牌
		if(!"".equals(searchMap.get("brand"))  )	{
			FilterQuery filterQuery=new SimpleFilterQuery();
			Criteria filterCriteria=new Criteria("item_brand").is(searchMap.get("brand"));
			filterQuery.addCriteria(filterCriteria);
			query.addFilterQuery(filterQuery);
		}
		//1.4 按规格过滤
		if(searchMap.get("spec")!=null){
			Map<String,String> specMap= (Map<String, String>) searchMap.get("spec");
			for(String key :specMap.keySet()){

				FilterQuery filterQuery=new SimpleFilterQuery();
				Criteria filterCriteria=new Criteria("item_spec_"+key).is( specMap.get(key)  );
				filterQuery.addCriteria(filterCriteria);
				query.addFilterQuery(filterQuery);

			}

		}

		//1.5按价格筛选
		if(!"".equals(searchMap.get("price"))){
			String[] price = ((String) searchMap.get("price")).split("-");
			if(!"0".equals(price[0])){
				Criteria filterCriteria=new Criteria("item_price").greaterThanEqual(price[0]);
				FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
				query.addFilterQuery(filterQuery);
			}
			//如果区间终点不等于*
			if(!"*".equals(price[1])){
				Criteria filterCriteria=new Criteria("item_price").lessThanEqual(price[1]);
				FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
				query.addFilterQuery(filterQuery);
			}
		}


		//1.6分页查询
		//提取页码
		Integer pageNo= (Integer) searchMap.get("pageNo");

		if(pageNo==null){
			//默认第一页
			pageNo=1;
		}

		//获取每页记录数
		Integer pageSize=(Integer) searchMap.get("pageSize");

		if(pageSize==null){
			//默认每页 20条
			pageSize=20;
		}

		//设置solr搜索的从第几条开始展示
		query.setOffset((pageNo-1)*pageSize);
		query.setRows(pageSize);


		//***********  获取高亮结果集  ***********

		//获得高亮页面对象
		//获得高亮页对象,包含所有的高亮记录,一条记录为一个TbItem
		HighlightPage<TbItem> queryForHighlightPage = solrTemplate.queryForHighlightPage(query, TbItem.class);

		//获取所有的高亮记录,也就是所有的商品组成记录组成的list
		List<HighlightEntry<TbItem>> highlighted = queryForHighlightPage.getHighlighted();
		//循环高亮入口,获取每一条记录
		for (HighlightEntry<TbItem> h : highlighted) {
			//获取记录中的实体类
			TbItem item = h.getEntity();
			//h.getHighlights() 获取每条高亮记录的所有高亮域
			//  h.getHighlights().get(0).getSnipplets()获取第一个高亮域的内容
			//	h.getHighlights().get(0).getSnipplets().get(0) 一个高亮域中可能存在多值
			List<HighlightEntry.Highlight> highlights = h.getHighlights();
			List<String> snipplets = highlights.get(0).getSnipplets();

			if (highlights.size() > 0 && h.getHighlights().get(0).getSnipplets().size() > 0) {
				//设置高亮域的结果
				//item.setTitle(h.getHighlights().get(0).getSnipplets().get(0));
				item.setTitle(snipplets.get(0));
				System.out.println(h.getHighlights().get(0).getSnipplets().get(0));

			}
		}

		/**
		              * h.getHighlights() 获取每条高亮记录的所有高亮域  
		              * 在new HighlightOptions().addField("item_title")是添加的高亮域
		              * h.getHighlights().get(0).getSnipplets()获取第一个高亮域的内容
		              * h.getHighlights().get(0).getSnipplets().get(0) 一个高亮域中可能存在多值
		              * 取决于solr中的配置域的是否配置了multiValued是否为true
		              */

		//不进行如上操作,获取的是原生的对象,即是没有经过高亮处理的对象
		map.put("rows", queryForHighlightPage.getContent());

		//返回总页数
		map.put("totalPages", queryForHighlightPage.getTotalPages());
		//返回总记录数
		map.put("total", queryForHighlightPage.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> pages = solrTemplate.queryForGroupPage(query, TbItem.class);
		//根据列得到分组结果集
		GroupResult<TbItem> groupResult = pages.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;
	}



}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值