使用solr进行高亮显示、过滤、分组、分页排序查询

public class HighlightAndFilterQueryDemo {

	@Autowired
	private SolrTemplate solrTemplate;

	public  Map search(Map searchMap){
		Map map = new HashMap();
		//1、查询列表  "rows" : contentList
		map.putAll(searchWithHightlight(searchMap));
		//2、分组查询商品分类列表  "categoryList"  :  categoryList
		List<String> categoryList = searchCategoryList(searchMap);
		map.put("categoryList",categoryList);
		//3、查询品牌与规格列表
		String category = (String)searchMap.get("category");
		//用户选择了category,则品牌数据
		if(!category.equals("")){
			map.putAll(searchBrandAndSpecList(category));
		}else{ //用户为选择category分类,则默认按照第一个category显示get(0)
			map.putAll(searchBrandAndSpecList(category.get(0)));
		}
		return Map;
	}




	//高亮显示与过滤查询
	private Map searchWithHightlight(Map searchMap){
		Map map = new HashMap();

		//1、设置高亮选项
		//根据关键字查询,构建高亮显示查询对象
		HighlightQuery query = new SimpleHighlightQuery();
		//addField(String fieldName) 在哪一个域上高亮显示,此处设置在title高亮显示 
		HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");
		//设置前缀
		highlightOptions.setSimplePrefix("<em style='color:red'>");
		//设置后缀
		highlightOptions.setSimplePostfix("</em>");
		//为查询对象设置高亮选项
		query.setHighlightoptions(highlightOptions);



		//2、构建查询条件
		//关键字查询 param为fieldName
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); 
		query.addCriteria(criteria);

		//2.1、按商品分类过滤查询
		//因为前端已经初始化了map中key为category,值为'',否则会报undefined
		//若用户点击了category分类,才添加条件
		if(!"".equals(searchMap.get("category"))){
			FilterQuery filterQuery = new SimpleFilterQuery();
			//创建filterCriteria的Criteria
			Criteria filterCriteria = new Criteria("item_category").is(searchMap.get("category"));
			filterQuery.addCriteria(filterCriteria);
			//添加过滤查询条件
			query.addFilterQuery(filterQuery);
		}

		//2.2、按照品牌过滤查询(与上述的分类一致)
		if(!"".equals(searchMap.get("brand"))){
			FilterQuery filterQuery = new SimpleFilterQuery();
			//创建filterCriteria的Criteria
			Criteria filterCriteria = new Criteria("item_brand").is(searchMap.get("brand"));
			filterQuery.addCriteria(filterCriteria);
			//添加过滤查询条件
			query.addFilterQuery(filterQuery);
		}

		//2.3、按规格过滤(前端传递过来的是一个map,则循环过滤即可)
		if(searchMap.get("spec")!=null){
			Map<Stirng,String> specMap = (Map<String,String>)searchMap.get("spec");
			for(String key : specMap.keySet()){
				FilterQuery filterQuery = new SimpleFilterQuery();
				//创建filterCriteria的Criteria
				//注意:此时是动态域  item_spec_*
				Criteria filterCriteria = new Criteria("item_spec_"+ key).is(specMap.get(key));
				filterQuery.addCriteria(filterCriteria);
				//添加过滤查询条件
				query.addFilterQuery(filterQuery);
			}
		}


		//2.4、按价格过滤
		if(!"".equals(searchMap.get("price"))){
			String[] price = (searchMap.get("price")).split("-");
			if(!price[0].equals("0")){ //如果最低价格不等于0
				FilterQuery filterQuery = new SimpleQuery();
				Criteria filterCriteria = new Criteria("item_price").greaterThanEqual(price[0]);
				filterQuery.addCriteria(filterCriteria);
				query.addFilterQuery(filterQuery);
			}
			tring[] price = (searchMap.get("price")).split("-");
			if(!price[1].equals("*")){ //如果最高价格不等于*,则限制最高价格
				FilterQuery filterQuery = new SimpleQuery();
				Criteria filterCriteria = new Criteria("item_price").lessThanEqual(price[1]);
				filterQuery.addCriteria(filterCriteria);
				query.addFilterQuery(filterQuery);
			}
		}


		//2.5、分页 query.setOffset(index);   query.setRows(pageSize);
		//获取前端给的页码与每页显示数量
		Integer pageNo= (Integer) searchMap.get("pageNo");//提取页码
		if(pageNo==null){
			pageNo=1;//默认第一页
		}
		Integer pageSize=(Integer) searchMap.get("pageSize");//每页记录数 
		if(pageSize==null){
			pageSize=20;//默认每页显示20条
		}
		//分页处理   setOffset()起始索引    setRows()每页显示条数
		query.setOffset((pageNo-1)*pageSize);//从第几条记录查询
		query.setRows(pageSize);
		//注意,前端还需要显示的总页数,总条数
		map.put("totalPages",page.getTotalPages());	
		map.put("totalCount",page.getTotalElements());




		//2.6排序 query.addsort(Sort sort);
		//Sort sort = new Sort(direction,properties); direction为枚举
		//ASC升序, DEC降序    properties为对哪个field进行排序
		//前端传递sort:(升序降序)    sortField:(对哪个字段进行排序)
		String sortValue= (String) searchMap.get("sort");//ASC  DESC  
		String sortField= (String) searchMap.get("sortField");//排序字段
		if(sortValue!=null && !sortValue.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);
			}			
		}




		//3、获取查询结果
		//此处传入的param1:query为HighlightQuery,为Query的子接口
		HighlightPage<TbItem> page = solrTemplate.queryForHightlightPage(query,TbItem.class);

		//page.getContent()为获取原生结果,不带高亮显示,若想高亮显示,则
		//得到的是高亮入口集合
		//第一个List
		List<HighlightEntry<TbItem>> entryList = page.getHighlighted();
		for(HighlightEntry<TbItem> entry:entryList){
			//获取高亮列表
			//第二个List
			List<Highlight> highlightList = entry.getHighlights();
			/*
			for(Highlight highlight :highlightList){
				第三个List
				List<String> list = highlight.getSnipplets();
			}
			*/
			//由于我们只对一个域设置高亮,即只addField(fieldName)一次,
			//且我们未对item_title存储多值,即multiValued="false"
			//第二第三个List中都只有一个返回结果,则get(0)取第一个元素处理
			if(highlightList.size()>0 && highlightList.get(0).getSnipplets().size>0){
				//通过entry获取实例
				TbItem item = entry.getEntity();
				//替换title值为高亮显示<em style='color:red'>标题</em>
				String title = highlightList.get(0).getSnipplets().get(0);
				item.setTitle(title);
			}

		}
		 map.put("rows",page.getContent());
		 return map;
	}


	/**
	* 分组查询
	*/
	private List<String> searchCategoryList(Map searchMap){
		List<String> list = new ArrayList();
		Query query = new SimpleQuery("*:*");
		//相当于关键字查询  where item_keywords = #{keywords}
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));

		//根据哪个域进行分组,相当于group by item_category;
		GroupOptions groupOptions = new GroupOptions().addGroupByField("item_category");
		query.setGroupOptions();

		//获取分组页
		GroupPage<TbItem> page = solrTemplate.queryForGroupPage(query,TbItem.class);

		//page.getGroupResult(String arg0);取其中一个addGroupByField结果
		GroupResult<TbItem> groupResult = page.getGroupResult("item_category");
		//获取分组入口页
		Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();
		//获取分组入口集合
		List<GroupEntry<TbItem>> entryList = groupEntries.getContent();
		for(GroupEntry<TbItem> entry :entryList){
			list.add(entry.getGroupValue());
		}
		return list;
	}



	@Autowired
	private RedisTemplate redisTemplate;
	
	/**
	 * 根据商品分类名称查询品牌和规格列表
	 * @param category 商品分类名称
	 * @return
	 */
	private Map searchBrandAndSpecList(String category){
		Map map=new HashMap();
		//1.根据商品分类名称得到模板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);	
			System.out.println("品牌列表条数:"+brandList.size());
			
			//3.根据模板ID获取规格列表
			List specList = (List) redisTemplate.boundHashOps("specList").get(templateId);
			map.put("specList", specList);		
			System.out.println("规格列表条数:"+specList.size());
		}	
		
		return map;
	}

}

以上代码为记事本手写的,可能存在一些错误,但是总体思路是正确的,按照业务逻辑进行修改即可。

猜你喜欢

转载自blog.csdn.net/itcats_cn/article/details/81906678