Solr服务搭建
第一步:把solr 的压缩包上传到Linux系统
第二步:解压solr。
第三步:安装Tomcat,解压缩即可。
第四步:把solr.war部署到Tomcat下的webapp目录下。
第五步:启动Tomcat解压。
第六步:把/root/solr-4.10.3/example/lib/ext目录下的所有的jar包,添加到solr工程中。
第七步:创建一个solrhome。/example/solr目录就是一个solrhome。复制此目录到/usr/local/solr/solrhome
第八步:关联solr及solrhome。需要修改solr工程的web.xml文件。并将注释取消
第九步:启动Tomcat,访问http://127.0.0.1:8080/solr/
配置业务域
第一步:把中文分析器添加到工程中。
- 1、把IKAnalyzer2012FF_u1.jar添加到solr工程的lib目录下
- 2、把扩展词典、配置文件放到solr工程的WEB-INF/classes目录下。
第二步:配置一个FieldType,制定使用IKAnalyzer
- 修改Solr的schema.xml文件,添加FieldType:
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
第三步:配置业务域,type制定使用自定义的FieldType。
设置业务系统Field,不同的系统所需要的字段不同;经过分析本系统需要商品Id,商品标题,商品卖点,商品价格,商品图片,分类名称字段
<field name="item_title" type="text_ik"(使用中文编辑器) indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="long" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category_name" type="string" indexed="true" stored="true" />
<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/> // 将下面的3个字段复制到keyword字段
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_sell_point" dest="item_keywords"/>
<copyField source="item_category_name" dest="item_keywords"/>
示例:实现更新商品索引的方法
Service层
@Service @Transactional public class SearchItemServiceImpl implements SearchItemService { @Autowired private ItemMapper itemMapper; @Autowired private SolrServer solrServer; @Override public E3Result importItems() { try { // 1.查询到所有商品列表 List<SearchResult> list = itemMapper.selectAllItem(); // 2.导入索引库中 for (SearchResult searchResult: list) { // 创建文档对象 SolrInputDocument document = new SolrInputDocument(); // 向文档对象中添加域 document.addField("id",searchResult.getId()); document.addField("item_title",searchResult.getTitle()); document.addField("item_sell_point",searchResult.getSell_point()); document.addField("item_price",searchResult.getPrice()); document.addField("item_image",searchResult.getImage()); document.addField("item_category_name",searchResult.getCategory_name()); // 将文档添加到索引库中 solrServer.add(document); } // 3.提交 solrServer.commit(); return E3Result.ok(); } catch (Exception ex){ ex.printStackTrace(); return E3Result.build(500,"建立商品索引时失败"); } } }
Controller层
@Controller public class SearchContriller { @Autowired private SearchItemService searchItemService; @RequestMapping("/index/item/import") @ResponseBody public E3Result impotItemIndex() { return searchItemService.importItems(); } }
示例:实现搜索功能(非项目整合版)
@Test public void queryDocument() throws Exception { // 1.创建一个SolrServer对象 SolrServer solrServer = new HttpSolrServer("http://127.0.0.1:8080/solr"); // 2.创建一个查询对象,可以参考solr的后台的查询功能设置条件 SolrQuery query = new SolrQuery(); // 3.设置查询条件 // 1)设置查询字段的2中方法 //query.setQuery("手机"); query.set("q","手机"); // 2)设置分页条件,从第几条开始,取几条数据 query.setStart(1); query.setRows(2); // 3)开启高亮 query.setHighlight(true); // 4)设置那个字段高亮显示 query.addHighlightField("item_title"); // 5)设置高亮字段的头尾 query.setHighlightSimplePre("<em>"); query.setHighlightSimplePost("</em>"); // 4)设置搜索域 query.set("df", "item_title"); // 4.执行查询,得到一个QueryResponse对象。 QueryResponse queryResponse = solrServer.query(query); // 5.获取查询结果 // 1)获取查询结果总记录数 SolrDocumentList solrDocumentList = queryResponse.getResults(); System.out.println("查询结果总记录数:" + solrDocumentList.getNumFound()); // 2)取查询结果集 Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting(); for (SolrDocument solrDocument : solrDocumentList) { System.out.println(solrDocument.get("id")); // 3)取高亮后的结果集 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"); } System.out.println(title); System.out.println(solrDocument.get("item_sell_point")); System.out.println(solrDocument.get("item_price")); System.out.println(solrDocument.get("item_image")); System.out.println(solrDocument.get("item_category_name")); } }
示例:实现搜索功能(项目整合版)
Controller层
@Controller public class SearchController { @Autowired private SearchService searchService; // 搜索页面展示商品条数 @Value("${SEARCH_RESULT_ROWS}") private Integer SEARCH_RESULT_ROWS; @RequestMapping("/search") // @ResponseBody public String impotItemIndex(String keyword, @RequestParam(defaultValue="1") Integer page, Model model) throws Exception { // 由于是get请求,需要我们自己处理一下乱码问题 keyword = new String(keyword.getBytes("iso-8859-1"), "utf-8"); SearchList searchList = searchService.search(keyword, page, SEARCH_RESULT_ROWS); //把结果传递给页面 model.addAttribute("query", keyword); model.addAttribute("totalPages", searchList.getTotalPages()); model.addAttribute("page", page); model.addAttribute("recourdCount", searchList.getRecordCount()); model.addAttribute("itemList", searchList.getItemList()); //返回逻辑视图 return "search"; } }
Service层
@Service public class SearchServiceImpl implements SearchService { @Autowired private SearchDao searchDao; @Override public SearchList search(String keyword, Integer page, Integer rows) throws Exception { //创建一个SolrQuery对象 SolrQuery query = new SolrQuery(); //设置查询条件 query.setQuery(keyword); //设置分页条件 if (page <=0 ) page =1; query.setStart((page - 1) * rows); query.setRows(rows); //设置默认搜索域 query.set("df", "item_title"); //开启高亮显示 query.setHighlight(true); query.addHighlightField("item_title"); query.setHighlightSimplePre("<em style="color:red">"); query.setHighlightSimplePost("</em>"); //调用dao执行查询 SearchList searchList = searchDao.search(query); //计算总页数 Long recordCount = searchList.getRecordCount(); int totalPage = (int) (recordCount / rows); if (recordCount % rows > 0){ totalPage ++; } //添加到返回结果的页数 searchList.setTotalPages(totalPage); //返回结果 return searchList; } }
Dao层(去solr服务器执行查询)
/** * 商品搜索dao */ @Repository public class SearchDao { @Autowired private SolrServer solrServer; /** *根据查询条件查询索引库 */ public SearchList search(SolrQuery query) throws Exception { //根据query查询索引库 QueryResponse queryResponse = solrServer.query(query); //取查询结果。 SolrDocumentList solrDocumentList = queryResponse.getResults(); //取查询结果总记录数 long numFound = solrDocumentList.getNumFound(); SearchList result = new SearchList(); result.setRecordCount(numFound); //取商品列表,需要取高亮显示 Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting(); List<SearchResult> itemList = new ArrayList<>(); for (SolrDocument solrDocument : solrDocumentList) { SearchResult item = new SearchResult(); item.setId((String) solrDocument.get("id")); item.setCategory_name((String) solrDocument.get("item_category_name")); item.setImage((String) solrDocument.get("item_image")); item.setPrice((long) solrDocument.get("item_price")); item.setSell_point((String) solrDocument.get("item_sell_point")); //取高亮显示 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); //添加到商品列表 itemList.add(item); } result.setItemList(itemList); //返回结果 return result; } }
注意:由于我们数据库中image字段存的是xxx,xxx...这样的数据,所以我们要在SearchResult中提供一个get方法,获取images字段(返回String数组);前端使用images[0]方式获取
SearchResult.java
public class SearchResult implements Serializable { private String id; private String title; private String sell_point; private Long price; private String image; private String category_name; private String keywords; public String[] getImages() { if (StringUtils.isNoneBlank(image)){ return image.split(","); } return null; }
SearchList.java
public class SearchList implements Serializable{ private Long recordCount; private List<SearchResult> itemList; private Integer totalPages;