solr的条件查询

结合实际项目中使用solr的条件查询

package com.pinyougou.search.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.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.SimpleFacetQuery;
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.HighlightPage;
import org.springframework.data.solr.core.query.result.ScoredPage;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.search.service.ItemSearchService;

/**

  • 搜索serviceimpl
  • @author Administrator

*/
@SuppressWarnings(“all”)
@Service(timeout = 10000)
public class ItemSearchServiceImpl implements ItemSearchService {

@Autowired
private SolrTemplate solrTemplate;

/**
 * 搜索
 */
@Override
public Map<String, Object> search(Map searchMap) {

    Map<String, Object> map = new HashMap<>();
    Query query = new SimpleQuery();
    Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
    query.addCriteria(criteria);
    ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
    map.put("rows", page.getContent());

    return map;
}

/**
 * 搜索高亮显示
 * 
 * @param searchMap
 * @return
 */
@Override
public Map<String, Object> searchHighlight(Map searchMap) {
    Map<String, Object> map = new HashMap<>();
    map.putAll(searchMap(searchMap));
    List categoryList = searchCategoryList(searchMap);
    map.put("categoryList", categoryList);

    // 查看是否传入了商品分类
    String category = (String) searchMap.get("category");
    if (category != "") {// 如果有商品分类(注意:商品分类只能选一个),那就按照商品分类返回规格和品牌
        map.putAll(searchBrandAndSpecList(category));
    } else {
        if (categoryList.size() > 0) {
            map.putAll(searchBrandAndSpecList((String) categoryList.get(0)));
        }
    }

    return map;
}

/**
 * 返回值也可以是List,Map更易于扩展
 * 
 * @param searchMap
 * @return
 */
private Map searchMap(Map searchMap) {
    Map<String, Object> map = new HashMap<>();
    // 高亮显示设置
    HighlightQuery query = new SimpleHighlightQuery();
    HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");// 设置高亮字段
    highlightOptions.setSimplePrefix("<em style='color:red'>");// 设置高亮前缀
    highlightOptions.setSimplePostfix("</em>");// 设置高亮后缀
    query.setHighlightOptions(highlightOptions);// 设置高亮选项

    // 1、按照关键字查询(关键字有可能被用户在中间加入空格,所以要去空格)
    String keywords = (String) searchMap.get("keywords");
    searchMap.put("keywords", keywords.replace(" ", ""));//取出所有空格
    Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
    query.addCriteria(criteria);


    // 2、按照商品分类查询
    if (!"".equals(searchMap.get("category"))) {
        Criteria filterCriteria = new Criteria("item_category").is(searchMap.get("category"));
        FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
        query.addFilterQuery(filterQuery);
    }


    // 3、按照品牌查询
    if (!"".equals(searchMap.get("brand"))) {
        Criteria filterCriteria = new Criteria("item_brand").is(searchMap.get("brand"));
        FilterQuery filterQuery = new SimpleFilterQuery(filterCriteria);
        query.addFilterQuery(filterQuery);
    }


    // 4、按照规格查询
    if (searchMap.get("spec") != null) {
        Map<String, String> specMap = (Map) searchMap.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、按照价格区间查询
    if (!"".equals(searchMap.get("price"))) {

        String[] price =((String) searchMap.get("price")).split("-");

        if(!price[0].equals("0")){//最低价格不是0,最低价格就是price[0]
            Criteria filterCriteria=new Criteria("item_price").greaterThanEqual(price[0]);
            FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
            query.addFilterQuery(filterQuery); 
        }

        if(!price[1].equals("*")){//最高价格不是*,最高价格就是price[1]
            Criteria filterCriteria=new Criteria("item_price").lessThanEqual(price[1]);
            FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
            query.addFilterQuery(filterQuery); 
        }

    }


    // 6、分页查询
    Integer pageNo = (Integer) searchMap.get("pageNo");//获取前端传入的查询第几页的页码
    if(pageNo == null){//如果没有传入值,默认为1
        pageNo = 1;
    }
    Integer pageSize = (Integer) searchMap.get("pageSize");//每页查询多少条
    if(pageSize == null){//如果没有传入值,默认为20
        pageSize = 20;
    }
    query.setOffset((pageNo-1)*pageSize);//从第几条记录查询
    query.setRows(pageSize);


    //7、按照升降序条件查询
    String sortValue = (String) searchMap.get("sort");
    String sortField = (String) searchMap.get("sortField");

    if(sortField != null && !sortField.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);
        }

    }

    // 根据条件查询,返回高亮显示结果
    HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class);

    // 高亮显示获取结果
    for (HighlightEntry<TbItem> h : page.getHighlighted()) {// 循环高亮入口集合
        TbItem item = h.getEntity();
        if (h.getHighlights().size() > 0 && h.getHighlights().get(0).getSnipplets().size() > 0) {
            item.setTitle(h.getHighlights().get(0).getSnipplets().get(0));// 设置高亮显示结果。因为只有一个高亮域“.addField("item_title")”,所以不需要遍历,直接取第一个
        }
    }

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

    map.put("totalPages", page.getTotalPages());//返回总页数
    map.put("total", page.getTotalElements());//返回总记录数
    return map;
}

/**
 * 查询分类列表
 * 
 * @param searchMap
 * @return
 */
private List searchCategoryList(Map searchMap) {

    List<String> list = new ArrayList();

    Query query = new SimpleQuery();
    // 按照关键字查询
    Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
    query.addCriteria(criteria);

    // 设置分组选项
    GroupOptions groupOptions = new GroupOptions().addGroupByField("item_category");
    query.setGroupOptions(groupOptions);

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

    // 根据列得到分组结果集(这个域必须要是上面关键字查询集合中的一个,应为上面有可能有多个,这里是分开查询的,一个字段对应一个解决)
    GroupResult<TbItem> groupResult = page.getGroupResult("item_category");

    // 得到分页结果入口页
    Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();

    // 得到分组入口集合
    List<GroupEntry<TbItem>> content = groupEntries.getContent();

    for (GroupEntry<TbItem> entry : content) {
        list.add(entry.getGroupValue());// 将分组结果的名称分装到返回值中
    }
    return list;
}

@Autowired
private RedisTemplate redisTemplate;

/**
 * 查询品牌和规格列表(从缓存中获取数据)
 * 
 * @param category
 * @return
 */
private Map searchBrandAndSpecList(String category) {

    Map map = new HashMap();

    // 1、先从Redis中根据商品分类名称获取模版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);

        // 3、根据模版ID获取规格列表
        List specList = (List) redisTemplate.boundHashOps("specList").get(templateId);
        map.put("specList", specList);
    }

    return map;
}

}


版权声明:本文为yb13215657368原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。