Spring data Solr(使用二)

1.高亮显示
@Autowired
    private SolrTemplate solrTemplate;

    @Override
    public Map<String, Object> searchItem(Map<String, Object> searchMap) {
        //简单查询开始----------------------------------------------
        // Query query = new SimpleQuery("*:*");
        // // 构建查询条件
        // String keywords = (String) searchMap.get("keywords");
        // Criteria criteria = new Criteria("item_keywords").is(keywords);
        // query.addCriteria(criteria);
        // // 执行查询
        // ScoredPage<TbItem> pageResult = solrTemplate.queryForPage(query, TbItem.class);
        // // 返回查询结果
        // Map<String, Object> resultMap = new HashMap<String, Object>();
        // resultMap.put("rows", pageResult.getContent());
        //简单查询结束----------------------------------------------
        //高亮显示查询开始-------------------------------------------
        // 构建高亮域选项
        HighlightQuery query = new SimpleHighlightQuery();
        HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");// 设置高亮域
        highlightOptions.setSimplePrefix("<em style='color:red'>");// 高亮前缀
        highlightOptions.setSimplePostfix("</em>");// 高亮后缀
        query.setHighlightOptions(highlightOptions);
        // 设置查询条件
        String keywords = (String) searchMap.get("keywords");
        Criteria criteria = new Criteria("item_keywords").is(keywords);
        query.addCriteria(criteria);
        // 执行查询
        HighlightPage<TbItem> pageResult = solrTemplate.queryForHighlightPage(query, TbItem.class);
        // 获取高亮入口集合
        List<HighlightEntry<TbItem>> entrys = pageResult.getHighlighted();
        for (HighlightEntry<TbItem> highlightEntry : entrys) {
            // 获取所有高亮域
            List<Highlight> highlights = highlightEntry.getHighlights();
            // for (Highlight highlight : highlights) {
            // 可能存在多值
            // List<String> snipplets = highlight.getSnipplets();
            // }
            // 得到第一个域的第一个值得高亮
            if (highlights != null && highlights.size() > 0 && highlights.get(0).getSnipplets() != null
                    && highlights.get(0).getSnipplets().size() > 0) {
                TbItem entity = highlightEntry.getEntity();
                String highlightTitle = highlights.get(0).getSnipplets().get(0);
                entity.setTitle(highlightTitle);
            }

        }
        //高亮显示查询结束-------------------------------------------
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("rows", pageResult.getContent());
        return resultMap;
    }
2.分组查询
 private List<String> searchGroupByCategory(Map<String, Object> searchMap) {
        List<String> searchList = new ArrayList<String>();
        // 构建分页 group by
        Query query = new SimpleQuery("*:*");
        GroupOptions GroupOptions = new GroupOptions().addGroupByField("item_category");
        query.setGroupOptions(GroupOptions);
        // 构建关键字查询 where
        Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
        query.addCriteria(criteria);
        // 执行查询,获取分组页对象
        GroupPage<TbItem> groupPage = solrTemplate.queryForGroupPage(query, TbItem.class);
        // 获取item_category的分组结果
        GroupResult<TbItem> groupResult = groupPage.getGroupResult("item_category");
        // 获取分页入口页
        Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();
        // 获取分组结果集
        List<GroupEntry<TbItem>> content = groupEntries.getContent();
        for (GroupEntry<TbItem> groupEntry : content) {
            String groupValue = groupEntry.getGroupValue();// 手机 电脑 衣服
            searchList.add(groupValue);
        }
        return searchList;
    }
3.过滤字段
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
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.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.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.HighlightEntry.Highlight;
import org.springframework.data.solr.core.query.result.HighlightPage;

import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.pojo.TbSpecification;
import com.pinyougou.search.service.ItemSearchService;

/**
 * 索引库管理 Service
 * 
 * @author Administrator
 *
 */
@Service
public class ItemSearchServiceImpl implements ItemSearchService {

    @Autowired
    private SolrTemplate solrTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

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

        // 创建返回对象
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 1.高亮显示查询
        Map<String, Object> highlightMap = searchHighlight(searchMap);
        resultMap.putAll(highlightMap);
        // 2.分组查询
        List<String> categoryList = searchGroupByCategory(searchMap);
        resultMap.put("categoryList", categoryList);
        // 3.根据分组查询出的分类名称查询规格和品牌列表
        String category = (String) searchMap.get("category");
        if (StringUtils.isNotBlank(category)) {
            // 用户点击了分类
            Map<String, Object> brandListAndSpecList = searchBrandListAndSpecList(category);
            resultMap.putAll(brandListAndSpecList);
        } else {
            // 初始化分类名称,获取第一个分类名称进行查询
            if (categoryList != null && categoryList.size() > 0) {
                Map<String, Object> brandListAndSpecList = searchBrandListAndSpecList(categoryList.get(0));
                resultMap.putAll(brandListAndSpecList);
            }
        }
        return resultMap;
    }

    /**
     * 高亮显示查询
     */
    @SuppressWarnings("all")
    private Map<String, Object> searchHighlight(Map<String, Object> searchMap) {
        // 1.1 构建高亮域选项
        HighlightQuery query = new SimpleHighlightQuery();
        HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");// 设置高亮域
        highlightOptions.setSimplePrefix("<em style='color:red'>");// 高亮前缀
        highlightOptions.setSimplePostfix("</em>");// 高亮后缀
        query.setHighlightOptions(highlightOptions);
        // 1.2 设置查询条件
        String keywords = (String) searchMap.get("keywords");
        Criteria criteria = new Criteria("item_keywords").is(keywords);
        query.addCriteria(criteria);
        // 1.3 设置分类过滤
        if (StringUtils.isNotBlank((String) searchMap.get("category"))) {
            Criteria categoryCriteria = new Criteria("item_category").is(searchMap.get("category"));
            FilterQuery filterQuery = new SimpleFilterQuery().addCriteria(categoryCriteria);
            query.addFilterQuery(filterQuery);
        }
        // 1.4 设置品牌过滤
        if (StringUtils.isNotBlank((String) searchMap.get("brand"))) {
            Criteria brandCriteria = new Criteria("item_brand").is(searchMap.get("brand"));
            FilterQuery filterQuery = new SimpleFilterQuery().addCriteria(brandCriteria);
            query.addFilterQuery(filterQuery);
        }
        // 1.5 设置规格选项过滤(数据格式 Map 动态域)
        if (searchMap.get("spec") != null) {
            Map<String, String> specMap = (Map<String, String>) searchMap.get("spec");
            for (String key : specMap.keySet()) {
                Criteria specCriteria = new Criteria("item_spec_" + key).is(specMap.get(key));
                FilterQuery filterQuery = new SimpleFilterQuery().addCriteria(specCriteria);
                query.addFilterQuery(filterQuery);
            }
        }
        // 1.6 执行查询并处理结果
        HighlightPage<TbItem> pageResult = solrTemplate.queryForHighlightPage(query, TbItem.class);
        // 获取高亮入口集合
        List<HighlightEntry<TbItem>> entrys = pageResult.getHighlighted();
        for (HighlightEntry<TbItem> highlightEntry : entrys) {
            // 获取所有高亮域
            List<Highlight> highlights = highlightEntry.getHighlights();
            // for (Highlight highlight : highlights) {
            // 可能存在多值
            // List<String> snipplets = highlight.getSnipplets();
            // }
            // 得到第一个域的第一个值得高亮
            if (highlights != null && highlights.size() > 0 && highlights.get(0).getSnipplets() != null
                    && highlights.get(0).getSnipplets().size() > 0) {
                TbItem entity = highlightEntry.getEntity();
                String highlightTitle = highlights.get(0).getSnipplets().get(0);
                entity.setTitle(highlightTitle);
            }

        }
        // 1.4 结果返回
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("rows", pageResult.getContent());
        return resultMap;
    }

    /**
     * 分组查询
     */
    private List<String> searchGroupByCategory(Map<String, Object> searchMap) {
        List<String> searchList = new ArrayList<String>();
        // 2.1 构建分页 group by
        Query query = new SimpleQuery("*:*");
        GroupOptions GroupOptions = new GroupOptions().addGroupByField("item_category");
        query.setGroupOptions(GroupOptions);
        // 2.2 构建关键字查询 where
        Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
        query.addCriteria(criteria);
        // 2.3 执行查询,并处理结果
        GroupPage<TbItem> groupPage = solrTemplate.queryForGroupPage(query, TbItem.class);
        // 获取item_category的分组结果
        GroupResult<TbItem> groupResult = groupPage.getGroupResult("item_category");
        // 获取分页入口页
        Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();
        // 获取分组结果集
        List<GroupEntry<TbItem>> content = groupEntries.getContent();
        for (GroupEntry<TbItem> groupEntry : content) {
            String groupValue = groupEntry.getGroupValue();// 手机 电脑 衣服
            searchList.add(groupValue);
        }
        // 2.4 结果返回
        return searchList;
    }

    /**
     * 加载品牌列表和规格列表
     */
    @SuppressWarnings("unchecked")
    private Map<String, Object> searchBrandListAndSpecList(String categoryName) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 3.1 根据分类名称从缓存中获取模板ID
        Object typeTemplateId = redisTemplate.boundHashOps("itemCat").get(categoryName);
        if (typeTemplateId != null) {
            // 3.2 根据模板ID查询从缓存中获取品牌列表
            List<TbBrand> brandList = (List<TbBrand>) redisTemplate.boundHashOps("brandList").get(typeTemplateId);
            // 3.3 根据模板ID查询从缓存中获取规格列表
            List<TbSpecification> specList =
                    (List<TbSpecification>) redisTemplate.boundHashOps("specList").get(typeTemplateId);
            // 3.4 组装返回结果
            resultMap.put("brandList", brandList);
            resultMap.put("specList", specList);
        }
        return resultMap;
    }

}
4.区间过滤
// 1.6 价格区间过滤
        if (StringUtils.isNotBlank((String) searchMap.get("price"))) {
            String[] price = ((String) searchMap.get("price")).split("-");
            if (!"0".equals(price[0])) {// 最小价格不等于0
                Criteria priceCriteria = new Criteria("item_price").greaterThanEqual(price[0]);
                FilterQuery filterQuery = new SimpleFilterQuery().addCriteria(priceCriteria);
                query.addFilterQuery(filterQuery);
            }
            if (!"*".equals(price[1])) {// 不等于最大价格,不做限制
                Criteria priceCriteria = new Criteria("item_price").lessThanEqual(price[1]);
                FilterQuery filterQuery = new SimpleFilterQuery().addCriteria(priceCriteria);
                query.addFilterQuery(filterQuery);
            }
        }
5.问题:关键字中有空格查询不出结果:

需要对关键字进行预处理

6.排序
// 1.8 排序
        String sortField = (String) searchMap.get("sortField");// 需要排序的字段
        String sort = (String) searchMap.get("sort");// 升序 ASC 降序 DESC
        if (StringUtils.isNotBlank(sortField)) {
            if ("ASC".equals(sort)) {
                query.addSort(new Sort(Sort.Direction.ASC, sortField));
            }
            if ("DESC".equals(sort)) {
                query.addSort(new Sort(Sort.Direction.DESC, sortField));
            }
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen-xs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值