《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/qq_42514129/article/details/84891115 「qq_42514129」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

摘要: 原创出处 http://www.iocoder.cn/Solr/install/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

package com.baidu.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.domain.Sort.Direction;
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 org.springframework.data.solr.core.query.result.ScoredPage;

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

@Service
public class ItemSearchServiceImpl implements ItemSearchService {

@Autowired
private SolrTemplate solrTemplate;

@Autowired
private RedisTemplate redisTemplate;

private Long totalElements;
private int totalPages;

/**
* 所有的查询
*/
@Override
public Map searchMap(Map<String, String> map) {
// TODO Auto-generated method stub
// 先判断map是否为空
if (map != null && map.get("keywords") != null && !map.get("keywords").trim().equals("")) {
Map resultMap = new HashMap();
// 高亮查询
List highlightList = searchHighlight(map);
resultMap.put("rows", highlightList);
// 分组查询
List categoryList = searchCategory(map);
resultMap.put("categoryList", categoryList);
// 根据分类名称查询模板ID
if (categoryList != null && categoryList.size() > 0) {
Long typeId = (Long) redisTemplate.boundHashOps("itemCatList").get(categoryList.get(0));
// 品牌查询
List brandList = searchBrandList(typeId);
resultMap.put("brandList", brandList);
// 规格选项查询
List specList = searchSpecList(typeId);
resultMap.put("specList", specList);
resultMap.put("totalElements", totalElements);
resultMap.put("totalPages", totalPages);
System.out.println("totalElements" + totalElements);
System.out.println("totalPages" + totalPages);
}

return resultMap;
}
// 根据关键字查询,必须要有关键字,否则前台给出提示
return null;
}

/**
* 分组查询
*
* @param map
* @return
*/
private List searchCategory(Map<String, String> map) {
List list = new ArrayList();
Query query = new SimpleQuery("*:*");
// 添加过滤查询
FilterQuery filterQuery = addFilterQuery(map);
query.addFilterQuery(filterQuery);
// 设置查询条件
Criteria criteria = new Criteria("item_keywords").contains(map.get("keywords"));
GroupOptions options = new GroupOptions().addGroupByField("item_category");
query.setGroupOptions(options);
// 执行查询,得到所有的分组数据
GroupPage<TbItem> groupPage = solrTemplate.queryForGroupPage(query, TbItem.class);
// 有可能指定了多个分组,所以根据指定的分组来获取分组结果
GroupResult<TbItem> groupResult = groupPage.getGroupResult("item_category");
// 获取分组入口对象
Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();
for (GroupEntry<TbItem> entry : groupEntries) {
String groupValue = entry.getGroupValue();
if (groupValue != null && !groupValue.equals("")) {
list.add(groupValue);
}
}

return list;
}

/**
* 高亮查询 + 分页结果 + 排序
*
* @param map
* @return
*/
private List searchHighlight(Map<String, String> map) {
Map highlightMap = new HashMap();
// 创建高亮查询对象
HighlightQuery query = new SimpleHighlightQuery();
query = addScoredPage(query, map);
query = addSort(query, map);
// 添加过滤查询
FilterQuery filterQuery = addFilterQuery(map);
query.addFilterQuery(filterQuery);
// 设置高亮显示的域
HighlightOptions options = new HighlightOptions().addField("item_title");
// 设置高亮前缀,后缀
options.setSimplePrefix("<em style='color:red'>");
options.setSimplePostfix("</em>");
// 绑定高亮域跟高亮查询
query.setHighlightOptions(options);
// 创建查询条件
Criteria criteria = new Criteria("item_keywords").contains(map.get("keywords"));
query.addCriteria(criteria);
HighlightPage<TbItem> highlightPage = solrTemplate.queryForHighlightPage(query, TbItem.class);
List<HighlightEntry<TbItem>> highlighted = highlightPage.getHighlighted(); // 高亮入口集合
for (HighlightEntry<TbItem> highlightEntry : highlighted) {
// 遍历高亮入口集合,得到高亮入口对象
TbItem entity = highlightEntry.getEntity(); // 获取原实体对象,需要往原实体对象的title中设置高亮数据
List<Highlight> highlights = highlightEntry.getHighlights();
// 获取单个document中的所有高亮数据集合,因为有可能HighlightOptions().addField("item_title")不只addFiled一个域
if (highlights != null && highlights.size() > 0) {
// 默认选中第一个域,即item.title
Highlight highlight = highlights.get(0);// 终于得到了一个高亮对象,但是有可能这条数据多次匹配了高亮数据,比如搜索手机,苹果手机 防水手机
if (highlight.getSnipplets() != null && highlight.getSnipplets().size() > 0) {
String title = highlight.getSnipplets().get(0);
System.out.println(title);
// 设置高亮结果
entity.setTitle(title); // 由于这是引用数据类型,在查询结果内部进行修改,那么原参数自然会被修改
}
}

}
totalElements = highlightPage.getTotalElements();
totalPages = highlightPage.getTotalPages();
return highlightPage.getContent();
}

/**
* 过滤查询
*
* @param map
* @return
*/
private FilterQuery addFilterQuery(Map map) {
// 创建过滤查询对象
FilterQuery query = new SimpleQuery();
// 过滤分类
String category = (String) map.get("category");
if (category != null && category.trim().length() > 0) {
// 说明不为空,过滤一下
Criteria criteria = new Criteria("item_category").contains(category);
query.addCriteria(criteria);
}
// 过滤品牌
String brand = (String) map.get("brand");
if (brand != null && brand.trim().length() > 0) {
// 说明不为空,过滤一下
Criteria criteria = new Criteria("item_brand").contains(brand);
query.addCriteria(criteria);
}
// 过滤规格选项
Map<String, String> specMap = (Map) map.get("spec");
if (specMap != null && specMap.size() > 0) {
// 说明不为空,过滤一下

for (String key : specMap.keySet()) {
Criteria criteria = new Criteria("item_spec_" + key).contains(specMap.get(key));
query.addCriteria(criteria);
}
}
// 过滤价格区间
String price_str = (String) map.get("price");
if (price_str != null && price_str.trim().length() > 0) {
// 说明不为空,过滤一下, 0-1000 1000-2000 3000-*
String[] strs = price_str.split("-");
if (!strs[0].equals("0")) {
// 说明不是0-1000,应该有下限
Criteria criteria = new Criteria("item_price").greaterThan(strs[0]);
query.addCriteria(criteria);
}
if (!strs[1].equals("*")) {
// 说明不是3000-*,说明应该有上限
Criteria criteria = new Criteria("item_price").lessThan(strs[1]);
query.addCriteria(criteria);
}
}
return query;
}

/**
* 添加商品分类
*
* @param t
* @param map
* @return
*/
private <T> T addScoredPage(T t, Map map) {
Integer currentPage = Integer.parseInt((String) map.get("currentPage"));
Integer size = Integer.parseInt((String) map.get("size"));

if (t instanceof SimpleQuery) {
// 分页查询
SimpleQuery query = (SimpleQuery) t;
if (currentPage == -1) {
currentPage = 1;
}
if (size == -1) {
size = 10;
}
query.setOffset((currentPage - 1) * size);// 计算出当前的页码
query.setRows(size);// 每页显示条数
}
if (t instanceof SimpleHighlightQuery) {
// 分页查询
SimpleHighlightQuery query = (SimpleHighlightQuery) t;
if (currentPage == -1) {
currentPage = 1;
}
if (size == -1) {
size = 10;
}
query.setOffset((currentPage - 1) * size);// 计算出当前的页码
query.setRows(size);// 每页显示条数
}

return t;
}

/**
* 排序
*
* @param t
* @param map
* @return
*/
private <T> T addSort(T t, Map<String, String> map) {
String sortField = map.get("sortField");
String sortType = map.get("sortType");
Direction asc = Sort.Direction.DESC;
if ("ASC".equals(sortType)) {
asc = Sort.Direction.ASC;
}
if (t instanceof SimpleQuery) {
SimpleQuery query = (SimpleQuery) t;
Sort sort = new Sort(asc, "item_" + sortField);
query.addSort(sort);
}
if (t instanceof SimpleHighlightQuery) {
SimpleHighlightQuery query = (SimpleHighlightQuery) t;
Sort sort = new Sort(asc, "item_" + sortField);
query.addSort(sort);
}
return t;
}

/**
* 默认根据第一个模板ID查询品牌列表
*
* @param templateId
* @return
*/
private List searchBrandList(Long templateId) {
List<Map> brandList = (List<Map>) redisTemplate.boundHashOps("brandList").get(templateId);
return brandList;
}

/**
* 默认根据第一个模板ID查询规格选项列表
*
* @param templateId
* @return
*/
private List searchSpecList(Long templateId) {
List specList = (List) redisTemplate.boundHashOps("specList").get(templateId);
System.out.println(specList);
return specList;
}

}

文章目录