首页 > 代码库 > 利用solr实现商品的搜索功能

利用solr实现商品的搜索功能

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。

Solr是一个全文检索服务器,只需要进行配置就可以实现全文检索服务。有效降低频繁访问数据库对数据库造成的压力。

第一步:将solr部署在linux系统下。

第二步:solrJ是solr的客户端,使用它需要依赖solrJ的jar包。

第三步:将数据库的内容添加到solr的索引库,这样查询就在索引库查询,而不是数据库了。

controller层:

@Controller
@RequestMapping("/manager")
public class ItemController {
 @Autowired
 private ItemService itemService;
 @RequestMapping("/importall")
 @ResponseBody
  public   TaotaoResult importAllItem(){
        	TaotaoResult result= itemService.importAllItem();
			return result;
 }
}
service层编写:
多表查询商品,显示在页面的逻辑编写:
mapper.java
package com.taotao.search.mapper;

import java.util.List;

import com.taotao.search.pojo.Item;

public interface ItemMapper {
	List<Item> getItemList();

}

  mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.taotao.search.mapper.ItemMapper">
<select id="getItemList" resultType="com.taotao.search.pojo.Item">
	SELECT
	a.id,
	a.title,
	a.sell_point,
	a.price,
	a.image,
	b. NAME category_name
	FROM
	tb_item a
	LEFT JOIN tb_item_cat b ON a.cid = b.id
</select>
</mapper>

技术分享

第四步:从索引库查询的逻辑编写:

//从索引库里面获取商品信息,现在这个dao层是从索引库获取信息,因为之前的写的逻辑是将db里面的数据导入到索引库。后面的查询都是从索引库中进行,而不从数据库了
@Repository
public class SearchDaoImpl implements SearchDao {
	@Autowired
	private SolrServer solrServer;

	@Override
	public SearchResult search(SolrQuery query) throws Exception {
		//这是从索引库里面,直接执行查询
		QueryResponse response = solrServer.query(query);
		//获取查询的结果
		SolrDocumentList documentList= response.getResults();
		
		SearchResult result=new SearchResult();
		//这是获取总记录数
		result.setRecordCount(documentList.getNumFound());
		
	 	List<Item> itemList=new ArrayList<>();
	 	//商品的高亮显示,即当鼠标移到字上时,该字体变色,这是从QueryResponse中获取的
	 	Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
	 	
		for (SolrDocument solrDocument : documentList) {
		    
			//每个SolrDocument都是一个商品pojo的内容,所以这里要创建一个商品的pojo对象,来获取详细的字段
		    Item item=new Item();
		    item.setId((String) solrDocument.get("id"));
		    //高亮显示是title的高亮显示
		    List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
		    String title="";
		    if (list!=null && list.size()>0) {
		    	title=list.get(0);	
			}
		    else{
		    	title=(String) solrDocument.get("item_title");	
		    }
		
		    item.setTitle(title);
		    item.setPrice((Long) solrDocument.get("item_price"));
		    item.setImage((String) solrDocument.get("item_image"));
		    item.setCategory_name((String) solrDocument.get(" item_category_name"));
		    item.setSell_point((String) solrDocument.get("item_sell_point"));
		   itemList.add(item); 
		}
		
		  result.setItemList(itemList);	
	
		return result;
	}

}

第五步:索引库内容建立好后,开始编写对外的服务接口,即通过条件搜索具体的商品,比如手机,会显示出总共的手机列表信息,第几页,总共多少页,总共多少个搜索结果

技术分享

 

请求的url:

           /search/query?q={查询条件}&page={page}&rows={rows}

返回的结果:TaotaoResult包装商品列表。

创建一个sql语句对应的pojo,单独建立一个pojo

用来装显示的内容列表:

public class Item {
     private String id;
     private String title;
     private String sell_point;
     private long price;
     private String image;
     private String category_name;
     private String item_des;

}

controller层:

@Controller
public class SearchController {
	@Autowired
	private SearchService searchService;
	
	@RequestMapping(value="http://www.mamicode.com/query", method=RequestMethod.GET)
	@ResponseBody
	public TaotaoResult search(@RequestParam("q")String queryString, 
			@RequestParam(defaultValue="http://www.mamicode.com/1")Integer page, 
			@RequestParam(defaultValue="http://www.mamicode.com/60")Integer rows) {
		//查询条件不能为空
		if (StringUtils.isBlank(queryString)) {
			return TaotaoResult.build(400, "查询条件不能为空");
		}
		SearchResult searchResult = null;
		try {
			queryString = new String(queryString.getBytes("iso8859-1"), "utf-8");
			searchResult = searchService.search(queryString, page, rows);
		} catch (Exception e) {
			e.printStackTrace();
			return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
		}
		return TaotaoResult.ok(searchResult);
		
	}	
	}


service层:利用solrJ的solrQurery来查询:

前提是要写好如何从索引库读取数据:  

下面是服务的接口层编写:

controller:

@Controller
public class SearchController {
	@Autowired
	private SearchService searchService;
	
	@RequestMapping(value="http://www.mamicode.com/query", method=RequestMethod.GET)
	@ResponseBody
	public TaotaoResult search(@RequestParam("q")String queryString, 
			@RequestParam(defaultValue="http://www.mamicode.com/1")Integer page, 
			@RequestParam(defaultValue="http://www.mamicode.com/60")Integer rows) {
		//查询条件不能为空
		if (StringUtils.isBlank(queryString)) {
			return TaotaoResult.build(400, "查询条件不能为空");
		}
		SearchResult searchResult = null;
		try {
			queryString = new String(queryString.getBytes("iso8859-1"), "utf-8");
			searchResult = searchService.search(queryString, page, rows);
		} catch (Exception e) {
			e.printStackTrace();
			return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
		}
		return TaotaoResult.ok(searchResult);
		
	}	
	}

  

@Service
public class SearchServiceImpl implements SearchService {
	@Autowired
	private SearchDao searchDao;
	

	@Override
	public SearchResult search(String queryString, int page, int rows) throws Exception {
	SolrQuery query=new SolrQuery();
	query.setQuery(queryString);
	query.setStart((page-1)*rows);
	query.setRows(rows);
	//设置默认的查询搜索域,即默认的查询
	query.set("df","item_keywords");
	//设置高亮显示
	query.setHighlight(true);
	
	query.addHighlightField("item_title");
	query.setHighlightSimplePre("<em style=\"color:red\">");
	query.setHighlightSimplePost("</em>");
//执行查询
	SearchResult searchResult = searchDao.search(query);
	//根据结果来计算商品总共多少页
	long recordCount=searchResult.getRecordCount();
	long pageCount=recordCount/rows;
	if (recordCount % rows > 0) {
		pageCount++;	
	}
	searchResult.setPageCount(pageCount);
	searchResult.setCurPage((long) page);
	
		return searchResult;
	}

}

 客户端通过输入商品来实现搜索功能:

controller层:

@Controller

public class SearchController {
	@Autowired
	private SearchService searchService;
	
	@RequestMapping("/search")
	public String search(@RequestParam("q")String queryString, @RequestParam(defaultValue="http://www.mamicode.com/1")Integer page, Model model) {
		if (queryString != null) {
			try {
				queryString = new String(queryString.getBytes("iso8859-1"), "utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		SearchResult searchResult = searchService.search(queryString, page);
		//向页面传递参数
		model.addAttribute("query", queryString);
		//model.addAttribute("totalPages", searchResult.getPageCount());
		model.addAttribute("itemList", searchResult.getItemList());
		model.addAttribute("page", page);
		
		return "search";
		
	}
}

  service层:

@Service
public class SearchServiceImpl implements SearchService {
	
   @Value("${SEARCH_BASE_URL}")
   private String SEARCH_BASE_URL;

	@Override
	public SearchResult search(String queryString, int page) {
		//这里需要的是连接+参数.这里每页显示的记录条数,可以传递也可以不用传递
		// 调用taotao-search的服务
		//查询参数
		Map<String, String> param = new HashMap<>();
		param.put("q", queryString);
		param.put("page", page + "");
		try {
			//调用服务
			String json = HttpClientUtil.doGet(SEARCH_BASE_URL, param);
			//把字符串转换成java对象
			TaotaoResult taotaoResult = TaotaoResult.formatToPojo(json, SearchResult.class);
			SearchResult result = (SearchResult) taotaoResult.getData();
			return result;
		/*	if (taotaoResult.getStatus() == 200) {
				
			}*/
			
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	
	}

}

  

 

 

 

利用solr实现商品的搜索功能