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));
            }
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章