Solr实现电商搜索


使用Solr实现电商网站中商品信息搜索功能,可以根据关键字、分类、价格搜索商品信息,也可以根据价格进行排序。
在这里插入图片描述
在一些大型门户网站、电子商务网站等都需要站内搜索功能,使用传统的数据库查询方式实现搜索无法满足一些高级的搜索需求,比如:搜索速度要快、搜索结果按相关度排序、搜索内容格式不固定等,这里就需要使用全文检索技术实现搜索功能。

使用Lucene实现

单独使用Lucene实现站内搜索需要开发的工作量较大,主要表现在:索引维护、索引性能优化、搜索性能优化等,因此不建议采用。

使用solr实现

基于Solr实现站内搜索扩展性较好并且可以减少程序员的工作量,因为Solr提供了较为完备的搜索引擎解决方案,因此在门户、论坛等系统中常用此方案。

原型分析

在这里插入图片描述

系统架构

在这里插入图片描述

controller

功能:接收页面传递过来的参数调用service查询商品列表。将查询结果返回给jsp页面,还需要查询参数的回显。

参数
1、查询条件:字符串
2、商品分类的过滤条件:商品的分类名称,字符串
3、商品价格区间:传递一个字符串,满足格式:“0-100、101-200、201-*”
4、排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序
5、分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。
6、Model:相当于request。

返回结果:String类型,就是一个jsp的名称。

@Controller
public class ProductController {

	@Autowired
	private ProductService productService;

	@RequestMapping("/list")
	public String productSearch(String queryString, String catalog_name, String price, String sort, Integer page,
			Model model) throws Exception {
		// 调用服务查询商品列表
		ResultModel resultModel = productService.queryProduct(queryString, catalog_name, price, sort, page);
		// 传递给页面
		model.addAttribute("queryString", queryString);
		model.addAttribute("catalog_name", catalog_name);
		model.addAttribute("price", price);
		model.addAttribute("sort", sort);
		model.addAttribute("page", page);
		model.addAttribute("result", resultModel);
		// 返回逻辑视图
		return "product_list";
	}

}

Service

功能:接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。接收返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。

参数
1、查询条件:字符串
2、商品分类的过滤条件:商品的分类名称,字符串
3、商品价格区间:传递一个字符串,满足格式:“0-100、101-200、201-*”
4、排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序
5、分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。

业务逻辑:
1、根据参数创建查询对象
2、调用dao执行查询。
3、根据总记录数计算总页数。

返回值: ResultModel

@Service
public class ProductService {

	private static final int PAGE_SIZE = 60;

	@Autowired
	private ProductDao productDao;

	public ResultModel queryProduct(String queryString, String caltalog_name, String price, String sort, Integer page)
			throws Exception {
		// 1、根据参数创建查询对象
		SolrQuery query = new SolrQuery();
		// 设置查询条件
		if (null != queryString && !"".equals(queryString)) {
			query.setQuery(queryString);
		} else {
			query.setQuery("*:*");
		}
		// 商品分类过滤
		if (null != caltalog_name && !"".equals(caltalog_name)) {
			query.addFilterQuery("product_catalog_name:" + caltalog_name);
		}
		// 价格区间过滤
		if (null != price && !"".equals(price)) {
			String[] strings = price.split("-");
			query.addFilterQuery("product_price:[" + strings[0] + " TO " + strings[1] + "]");
		}
		// 排序条件
		if ("1".equals(sort)) {
			query.setSort("product_price", ORDER.desc);
		} else {
			query.setSort("product_price", ORDER.asc);
		}
		// 分页处理
		if (page == null)
			page = 1;
		query.setStart((page - 1) * PAGE_SIZE);
		query.setRows(PAGE_SIZE);
		// 默认搜索域
		query.set("df", "product_keywords");
		// 设置高亮
		query.setHighlight(true);
		query.addHighlightField("product_name");
		query.setHighlightSimplePre("<em style=\"color:red\">");
		query.setHighlightSimplePost("</em>");
		// 2、调用dao执行查询。
		ResultModel resultModel = productDao.search(query);
		// 3、根据总记录数计算总页数。
		Long recordCount = resultModel.getRecordCount();
		long pageCount = recordCount / PAGE_SIZE;
		if (recordCount % PAGE_SIZE > 0) {
			pageCount++;
		}
		resultModel.setPageCount((int) pageCount);
		resultModel.setCurPage(page);
		// 返回结果
		return resultModel;
	}

}

Dao

功能: 接收service层传递过来的参数,根据参数查询索引库,返回查询结果。

参数: SolrQuery对象
返回值:一个商品列表List<ProductModel>,还需要返回查询结果的总数量。

返回: ResultModel

@Repository
public class ProductDao {

	@Autowired
	private SolrClient solrClient;

	public ResultModel search(SolrQuery query) throws Exception {
		// 执行查询
		QueryResponse response = solrClient.query(query);
		// 取查询结果
		SolrDocumentList solrDocumentList = response.getResults();
		// 取查询结果总记录数
		ResultModel resultModel = new ResultModel();
		resultModel.setRecordCount(solrDocumentList.getNumFound());
		// 商品列表
		List<ProductModel> productList = new ArrayList<>();
		// 取结果集
		for (SolrDocument solrDocument : solrDocumentList) {
			// 创建一个商品对象
			ProductModel productModel = new ProductModel();
			productModel.setPid((String) solrDocument.get("id"));
			productModel.setCatalog_name((String) solrDocument.get("product_catalog_name"));
			// 取高亮显示
			Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
			List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");
			String productName = "";
			if (list != null && list.size() > 0) {
				productName = list.get(0);
			} else {
				productName = (String) solrDocument.get("product_name");
			}
			productModel.setName(productName);
			productModel.setPicture((String) solrDocument.get("product_picture"));
			productModel.setPrice((float) solrDocument.get("product_price"));
			// 添加到商品列表
			productList.add(productModel);
		}
		// 添加到返回结果
		resultModel.setProductList(productList);
		return resultModel;
	}

}

返回值对象模型

public class ResultModel {
	// 商品列表
	private List<ProductModel> productList;
	// 商品总数
	private Long recordCount;
	// 总页数
	private int pageCount;
	// 当前页
	private int curPage;

	public List<ProductModel> getProductList() {
		return productList;
	}

	public void setProductList(List<ProductModel> productList) {
		this.productList = productList;
	}

	public Long getRecordCount() {
		return recordCount;
	}

	public void setRecordCount(Long recordCount) {
		this.recordCount = recordCount;
	}

	public int getPageCount() {
		return pageCount;
	}

	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}

	public int getCurPage() {
		return curPage;
	}

	public void setCurPage(int curPage) {
		this.curPage = curPage;
	}

}

商品对象模型

public class ProductModel {
	// 商品编号
	private String pid;
	// 商品名称
	private String name;
	// 商品分类名称
	private String catalog_name;
	// 价格
	private float price;
	// 商品描述
	private String description;
	// 图片名称
	private String picture;

	public String getPid() {
		return pid;
	}

	public void setPid(String pid) {
		this.pid = pid;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCatalog_name() {
		return catalog_name;
	}

	public void setCatalog_name(String catalog_name) {
		this.catalog_name = catalog_name;
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getPicture() {
		return picture;
	}

	public void setPicture(String picture) {
		this.picture = picture;
	}

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
    本课程全程使用目前比较流行的开发工具idea进行开发,涉及到目前互联网项目中最常用的高并发解决方案技术, 如dubbo,redis,solr,freemarker,activeMQ,springBoot框架,微信支付,nginx负载均衡,电商活动秒杀,springSecurity安全框架,FastDFS分布式文件服务器,还会涉及到代码生成器,   前台的技术有angularJS和BootStrap框架,此课程内容丰富实战性强,如果你还是传统项目的开发人员,那你学完本课程会有很大的收获,让你的薪资上涨,5K以上,让你完全感受到了互联网思维带来的高 并发解决方案的思路,如果你是开发的小白,建议你学完Spring,SpringMVC,MyBatis框架后再来学习本门课程,学完以后会让你完全体验到企业级开发的流程.在职开发人员学完后会让你的薪资更高,让你更了解互联网是如何解决高并发 学完SSM框架的同学就可以学习,能让你切身感受到企业级开发环境目标1:完成solr环境安装、中文分析器和业务域的配置目标2:会使用Spring Data Solr完成增删改查操作目标3:完成批量数据导入功能目标4:完成按关键字搜索功能目标5:实现考拉易购搜索结果高亮显示功能目标6:说出考拉易购搜索的业务规则和实现思路目标7:完成查询分类列表的功能目标8:完成缓存品牌和规格数据的功能目标9:完成显示品牌和规格数据的功能目标10:完成过滤条件构建的功能目标11:完成过滤查询的功能目标11:实现考拉易购价格区间筛选功能目标12:实现搜索结果分页功能目标13:理解多关键字搜索目标14:实现搜索结果排序功能目标15:实现隐藏品牌列表功能目标16:实现搜索页与首页对接功能目标17:完成更新索引库的功能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值