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 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("");
//设置后缀
highlightOptions.setSimplePostfix("");
//为查询对象设置高亮选项
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 specMap = (Map)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 page = solrTemplate.queryForHightlightPage(query,TbItem.class);
//page.getContent()为获取原生结果,不带高亮显示,若想高亮显示,则
//得到的是高亮入口集合
//第一个List
List> entryList = page.getHighlighted();
for(HighlightEntry entry:entryList){
//获取高亮列表
//第二个List
List highlightList = entry.getHighlights();
/*
for(Highlight highlight :highlightList){
第三个List
List 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值为高亮显示标题
String title = highlightList.get(0).getSnipplets().get(0);
item.setTitle(title);
}
}
map.put("rows",page.getContent());
return map;
}
/**
* 分组查询
*/
private List searchCategoryList(Map searchMap){
List 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 page = solrTemplate.queryForGroupPage(query,TbItem.class);
//page.getGroupResult(String arg0);取其中一个addGroupByField结果
GroupResult groupResult = page.getGroupResult("item_category");
//获取分组入口页
Page> groupEntries = groupResult.getGroupEntries();
//获取分组入口集合
List> entryList = groupEntries.getContent();
for(GroupEntry 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;
}
}
以上代码为记事本手写的,可能存在一些错误,但是总体思路是正确的,按照业务逻辑进行修改即可。