小編給大家分享一下如何使用solr實現商品的搜索功能,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
為什么要用solr服務,為什么要用luncence?
問題提出:當我們訪問購物網站的時候,我們可以根據我們隨意所想的內容輸入關鍵字就可以查詢出相關的內容,這是怎么做到呢?這些隨意的數據不可能是根據數據庫的字段查詢的,那是怎么查詢出來的呢,為什么千奇百怪的關鍵字都可以查詢出來呢?
答案就是全文檢索工具的實現,luncence采用了詞元匹配和切分詞。舉個例子:北京天安門------luncence切分詞:北京 京天 天安 安門 等等這些分詞。所以我們搜索的時候都可以檢索到。
有一種分詞器就是IKAnalyzer中文分詞器,它有細粒度切分和智能切分,即根據某種智能算法。
這就使用solr的最大的好處:檢索功能的實現。
使用步驟;
(1)solr服務器搭建,因為solr是用java5開發的,所以需要jdk和tomcat。搭建部署
(2)搭建完成后,我們需要將要展示的字段引入solr的庫中。配置spring與solr結合,工程啟動的時候啟動solr
(3)將數據庫中的查詢內容導入到solr索引庫,這里使用的是solrj的客戶端實現的。具體使用可以參考api
(4)建立搜索服務,供客戶端調用。調用solr,查詢內容,這中間有分頁功能的實現。solr高亮顯示的實現。
(5)客戶端接收頁面的請求參數,調用搜索服務,進行搜索。
業務字段判斷標準:
1、在搜索時是否需要在此字段上進行搜索。例如:商品名稱、商品的賣點、商品的描述
(這些相當于將標簽給了solr,導入商品數據后,solr對這些字段的對應的商品的具體內容進行分詞切分,然后,我們就可以搜索到相關內容了)
2、后續的業務是否需要用到此字段。例如:商品id。
需要用到的字段:
1、商品id
2、商品title
3、賣點
4、價格
5、商品圖片
6、商品分類名稱
7、商品描述
Solr中的業務字段:
1、id——》商品id
其他的對應字段創建solr的字段。
<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_desc" type="text_ik" indexed="true" stored="false" /> <field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/> <copyField source="item_title" dest="item_keywords"/> <copyField source="item_sell_point" dest="item_keywords"/> <copyField source="item_category_name" dest="item_keywords"/> <copyField source="item_desc" dest="item_keywords"/>
重新啟動tomcat
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;
}
}<br>service層編寫:<br>多表查詢商品,顯示在頁面的邏輯編寫:<br>mapper.javapackage 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="/query", method=RequestMethod.GET)
@ResponseBody
public TaotaoResult search(@RequestParam("q")String queryString,
@RequestParam(defaultValue="1")Integer page,
@RequestParam(defaultValue="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);
}
}<br><br><br>
1
<span >service層:利用solrJ的solrQurery來查詢:</span>前提是要寫好如何從索引庫讀取數據:
下面是服務的接口層編寫:
controller:
@Controller
public class SearchController {
@Autowired
private SearchService searchService;
@RequestMapping(value="/query", method=RequestMethod.GET)
@ResponseBody
public TaotaoResult search(@RequestParam("q")String queryString,
@RequestParam(defaultValue="1")Integer page,
@RequestParam(defaultValue="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="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實現商品的搜索功能”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。