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;