电商项目搜寻功能(分页,高亮,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(0));
            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<=0){
            pageNo=1;
        }
        Integer start = (pageNo - 1) * 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[0].equals("0")){
                Criteria filterCriteria = new Criteria("item_price").greaterThanEqual(split[0]);
                FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
                query.addFilterQuery(filterQuery);
            }
            if (!split[1].equals("*")){
                Criteria filterCriteria = new Criteria("item_price").lessThanEqual(split[1]);
                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()>0){
                // 获取高亮的标题集合
                List<String> highlightTitle = highlights.get(0).getSnipplets();
                if(highlightTitle!=null&&highlightTitle.size()>0){
                    // 获取高亮的标题
                    String title = highlightTitle.get(0);
                    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;

    }
}

 

posted @ 2019-11-25 22:33  王炬  阅读(514)  评论(0编辑  收藏  举报