java學習筆記——商城項目練習——solr服務的安裝與使用,數據庫數據導入solr索引庫,solrJ的使用,商城項目搜索功能實現

                                            1,Solr服務搭建

1.1.    Solr的環境
Solr是java開發。
需要安裝jdk。
安裝環境Linux。
需要安裝Tomcat。
1.2.    搭建步驟
第一步:把solr 的壓縮包上傳到Linux系統
第二步:解壓solr。
第三步:安裝Tomcat到目錄/usr/local/solr/下,解壓縮即可。
第四步:把solr部署到Tomcat下。
第五步:解壓縮war包。啓動Tomcat解壓。(war包在solr安裝包的dist文件夾中,跟他在一起的還有solrj.jar,不過這裏我們需要solrj,solrj我們是使用maven添加的依賴)
第六步:把/root/solr-4.10.3/example/lib/ext目錄下的所有的jar包,添加到solr工程中。
[root@localhost ext]# pwd
/root/solr-4.10.3/example/lib/ext
[root@localhost ext]# cp * /usr/local/solr/tomcat/webapps/solr/WEB-INF/lib/
第七步:創建一個solrhome。/example/solr目錄就是一個solrhome。複製此目錄到/usr/local/solr/solrhome
[root@localhost example]# pwd
/root/solr-4.10.3/example
[root@localhost example]# cp -r solr /usr/local/solr/solrhome
[root@localhost example]#
第八步:關聯solr及solrhome。需要修改solr工程的web.xml文件。

第九步:啓動Tomcat
http://192.168.25.154:8080/solr/
和windows下的配置完全一樣。

 

1.3.    配置業務域
schema.xml中定義
1、商品Id
2、商品標題
3、商品賣點
4、商品價格
5、商品圖片
6、分類名稱

創建對應的業務域。需要制定中文分析器。

創建步驟:
第一步:把中文分析器添加到工程中。
1、把IKAnalyzer2012FF_u1.jar添加到solr工程的lib目錄下
2、WEB-INF/下創建classes目錄,把擴展詞典、配置文件放到solr工程的WEB-INF/classes目錄下。

第二步:配置一個FieldType,制定使用IKAnalyzer
修改schema.xml文件
修改Solr的schema.xml文件(位置在solrhome/collection1/conf/目錄下),添加FieldType:

<fieldType name="text_ik" class="solr.TextField">

  <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>

</fieldType>

 第三步:配置業務域,type制定使用自定義的FieldType。
設置業務系統Field

<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"/>

<copyField source="item_title" dest="item_keywords"/>

<copyField source="item_sell_point" dest="item_keywords"/>

<copyField source="item_category_name" dest="item_keywords"/>

第四步:重啓tomcat

 

                                         2. 搜索工程搭建

要實現搜索功能,需要搭建solr服務、搜索服務工程、搜索系統

2.1.    搜索服務工程搭建
可以參考e3-manager創建。
e3-search(聚合工程pom)
        |--e3-search-interface(jar)
        |--e3-search-Service(war)
e3-search-web(war)

 

                                    3. 使用solrJ管理索引庫

使用SolrJ可以實現索引庫的增刪改查操作。

3.1.    添加文檔
第一步:把solrJ的jar包添加到工程中(我們的e3mall-parent父工程已經依賴了,直接在search工程的pom中添加依賴即可)。
第二步:創建一個SolrServer,使用HttpSolrServer創建對象。
第三步:創建一個文檔對象SolrInputDocument對象。
第四步:向文檔中添加域。必須有id域,域的名稱必須在schema.xml中定義。
第五步:把文檔添加到索引庫中。
第六步:提交。

@Test
	public void addDocument() throws Exception {
		// 第一步:把solrJ的jar包添加到工程中。
		// 第二步:創建一個SolrServer,使用HttpSolrServer創建對象。
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
		// 第三步:創建一個文檔對象SolrInputDocument對象。
		SolrInputDocument document = new SolrInputDocument();
		// 第四步:向文檔中添加域。必須有id域,域的名稱必須在schema.xml中定義。
		document.addField("id", "test001");
		document.addField("item_title", "測試商品");
		document.addField("item_price", "199");
		// 第五步:把文檔添加到索引庫中。
		solrServer.add(document);
		// 第六步:提交。
		solrServer.commit();
	}

3.2.    刪除文檔
3.2.1.    根據id刪除

第一步:創建一個SolrServer對象。
第二步:調用SolrServer對象的根據id刪除的方法。
第三步:提交。

@Test
	public void deleteDocumentById() throws Exception {
		// 第一步:創建一個SolrServer對象。
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
		// 第二步:調用SolrServer對象的根據id刪除的方法。
		solrServer.deleteById("1");
		// 第三步:提交。
		solrServer.commit();
	}

3.2.2.    根據查詢刪除

@Test
	public void deleteDocumentByQuery() throws Exception {
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
		solrServer.deleteByQuery("title:change.me");
		solrServer.commit();
	}

3.3.    查詢索引庫

查詢步驟:
第一步:創建一個SolrServer對象
第二步:創建一個SolrQuery對象。
第三步:向SolrQuery中添加查詢條件、過濾條件。。。
第四步:執行查詢。得到一個Response對象。
第五步:取查詢結果。
第六步:遍歷結果並打印。

3.3.1.    簡單查詢

@Test
	public void queryDocument() throws Exception {
		// 第一步:創建一個SolrServer對象
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
		// 第二步:創建一個SolrQuery對象。
		SolrQuery query = new SolrQuery();
		// 第三步:向SolrQuery中添加查詢條件、過濾條件。。。
		query.setQuery("*:*");
		// 第四步:執行查詢。得到一個Response對象。
		QueryResponse response = solrServer.query(query);
		// 第五步:取查詢結果。
		SolrDocumentList solrDocumentList = response.getResults();
		System.out.println("查詢結果的總記錄數:" + solrDocumentList.getNumFound());
		// 第六步:遍歷結果並打印。
		for (SolrDocument solrDocument : solrDocumentList) {
			System.out.println(solrDocument.get("id"));
			System.out.println(solrDocument.get("item_title"));
			System.out.println(solrDocument.get("item_price"));
		}
	}

3.3.2.    帶高亮顯示

@Test
	public void queryDocumentWithHighLighting() throws Exception {
		// 第一步:創建一個SolrServer對象
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
		// 第二步:創建一個SolrQuery對象。
		SolrQuery query = new SolrQuery();
		// 第三步:向SolrQuery中添加查詢條件、過濾條件。。。
		query.setQuery("測試");
		//指定默認搜索域
		query.set("df", "item_keywords");
		//開啓高亮顯示
		query.setHighlight(true);
		//高亮顯示的域
		query.addHighlightField("item_title");
		query.setHighlightSimplePre("<em>");
		query.setHighlightSimplePost("</em>");
		// 第四步:執行查詢。得到一個Response對象。
		QueryResponse response = solrServer.query(query);
		// 第五步:取查詢結果。
		SolrDocumentList solrDocumentList = response.getResults();
		System.out.println("查詢結果的總記錄數:" + solrDocumentList.getNumFound());
		// 第六步:遍歷結果並打印。
		for (SolrDocument solrDocument : solrDocumentList) {
			System.out.println(solrDocument.get("id"));
			//取高亮顯示
			Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
			List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
			String itemTitle = null;
			if (list != null && list.size() > 0) {
				itemTitle = list.get(0);
			} else {
				itemTitle = (String) solrDocument.get("item_title");
			}
			System.out.println(itemTitle);
			System.out.println(solrDocument.get("item_price"));
		}
	}

                           

                                  4.    把商品數據導入到索引庫中

4.1.    Dao層
4.1.1.    Sql語句

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
WHERE a.`status`=1

需要自己創建Mapper文件。 

4.1.2.    創建對應數據集的pojo

public class SearchItem implements Serializable{
	private String id;
	private String title;
	private String sell_point;
	private long price;
	private String image;
	private String category_name;
}

4.1.3.    接口定義

public interface ItemMapper {

	List<SearchItem> getItemList();
}

4.1.4.    Mapper映射文件

<?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="cn.e3mall.search.mapper.ItemMapper" >
	
	<select id="getItemList" resultType="cn.e3mall.common.pojo.SearchItem">
		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
		WHERE a.`status`=1
	</select>

</mapper>

4.2.    Service層
4.2.1.    功能分析

1、查詢所有商品數據。
2、循環把商品數據添加到索引庫。使用solrJ實現。
3、返回成功。返回E3Result

參數:無
返回值:E3Result
4.2.2.    solrJ添加索引庫
1、把solrJ的jar包添加到工程。
2、創建一個SolrServer對象。創建一個和sorl服務的連接。HttpSolrServer。
3、創建一個文檔對象。SolrInputDocument。
4、向文檔對象中添加域。必須有一個id域。而且文檔中使用的域必須在schema.xml中定義。
5、把文檔添加到索引庫
6、Commit。

@Test
	public void addDocument() throws Exception {
		// 1、把solrJ的jar包添加到工程。
		// 2、創建一個SolrServer對象。創建一個和sorl服務的連接。HttpSolrServer。
		//如果不帶Collection默認連接Collection1
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
		// 3、創建一個文檔對象。SolrInputDocument。
		SolrInputDocument document = new SolrInputDocument();
		// 4、向文檔對象中添加域。必須有一個id域。而且文檔中使用的域必須在schema.xml中定義。
		document.addField("id", "test001");
		document.addField("item_title", "測試商品");
		// 5、把文檔添加到索引庫
		solrServer.add(document);
		// 6、Commit。
		solrServer.commit();
	}

4.2.3.    代碼實現

/**
 * 將商品數據導入索引庫
 * <p>Title: SearchItemServiceImpl</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Service
public class SearchItemServiceImpl implements SearchItemService {

	@Autowired
	private ItemMapper itemMapper;
	@Autowired
	private SolrServer solrServer;
	
	@Override
	public E3Result importItmes() {
		try {
			//查詢商品列表
			List<SearchItem> itemList = itemMapper.getItemList();
			//導入索引庫
			for (SearchItem searchItem : itemList) {
				//創建文檔對象
				SolrInputDocument document = new SolrInputDocument();
				//向文檔中添加域
				document.addField("id", searchItem.getId());
				document.addField("item_title", searchItem.getTitle());
				document.addField("item_sell_point", searchItem.getSell_point());
				document.addField("item_price", searchItem.getPrice());
				document.addField("item_image", searchItem.getImage());
				document.addField("item_category_name", searchItem.getCategory_name());
				//寫入索引庫
				solrServer.add(document);
			}
			//提交
			solrServer.commit();
			//返回成功
			return E3Result.ok();
			
		} catch (Exception e) {
			e.printStackTrace();
			return E3Result.build(500, "商品導入失敗");
		}
	}

}

4.2.4.    SolrServer的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">

	<bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
		<constructor-arg index="0" value="http://192.168.25.154:8080/solr"/>
	</bean>

</beans>

4.2.5.    發佈服務

4.3.    表現層
後臺管理工程中調用商品導入服務。

4.3.1.    功能分析

請求的url:/index/item/import

響應的結果:json數據。可以使用E3Result

4.3.2.    Controller

@Controller
public class SearchItemController {

	@Autowired
	private SearchItemService searchItemService;
	
	@RequestMapping("/index/item/import")
	@ResponseBody
	public E3Result impotItemIndex() {
		E3Result result = searchItemService.importItmes();
		return result;
	}

}

4.4.    解決Mapper映射文件不存在異常
在e3-search-service的pom文件中需要添加資源配置。

<!-- 如果不添加此節點mybatis的mapper.xml文件都會被漏掉。 -->
	<build>
		<resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
	</build>

 

                                   5.    搜索功能實現


5.1.    使用sorlJ 查詢索引庫

//使用solrJ實現查詢
	@Test
	public void queryDocument() throws Exception {
		//創建一個SolrServer對象
		SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
		//創建一個查詢對象,可以參考solr的後臺的查詢功能設置條件
		SolrQuery query = new SolrQuery();
		//設置查詢條件
//		query.setQuery("阿爾卡特");
		query.set("q","阿爾卡特");
		//設置分頁條件
		query.setStart(1);
		query.setRows(2);
		//開啓高亮
		query.setHighlight(true);
		query.addHighlightField("item_title");
		query.setHighlightSimplePre("<em>");
		query.setHighlightSimplePost("</em>");
		//設置默認搜索域
		query.set("df", "item_title");
		//執行查詢,得到一個QueryResponse對象。
		QueryResponse queryResponse = solrServer.query(query);
		//取查詢結果總記錄數
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		System.out.println("查詢結果總記錄數:" + solrDocumentList.getNumFound());
		//取查詢結果
		Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
		for (SolrDocument solrDocument : solrDocumentList) {
			System.out.println(solrDocument.get("id"));
			//取高亮後的結果
			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"));
		}
		
	}

5.2.    功能分析
把搜索結果頁面添加到工程中。

請求的url:/search
請求的方法:GET
參數:
keyword:查詢條件
Page:頁碼。如果沒有此參數,需要給默認值1。
返回的結果:
1)商品列表
2)總頁數
3)總記錄數
使用jsp展示,返回邏輯視圖。

商品列表使用:SearchItem表示。
需要把查詢結果封裝到一個pojo中:
1)商品列表List<SearchItem>
2)總頁數。Int totalPages。總記錄數/每頁顯示的記錄數向上取整。把每頁顯示的記錄是配置到屬性文件中。
3)總記錄數。Int recourdCount

public class SearchResult implements Serializable {
	private List<SearchItem> itemList;
	private int totalPages;
	private int recourdCount;
}

5.3.    Dao層

跟據查詢條件查詢索引庫,返回對應的結果。

參數:SolrQuery

返回結果:SearchResult

@Repository
public class SearchDao {

	@Autowired
	private SolrServer solrServer;
	
	public SearchResult search(SolrQuery query) throws Exception {
		//根據查詢條件查詢索引庫
		QueryResponse queryResponse = solrServer.query(query);
		//取查詢結果總記錄數
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		long numFound = solrDocumentList.getNumFound();
		//創建一個返回結果對象
		SearchResult result = new SearchResult();
		result.setRecourdCount((int) numFound);
		//創建一個商品列表對象
		List<SearchItem> itemList = new ArrayList<>();
		//取商品列表
		//取高亮後的結果
		Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
		for (SolrDocument solrDocument : solrDocumentList) {
			//取商品信息
			SearchItem searchItem = new SearchItem();
			searchItem.setCategory_name((String) solrDocument.get("item_category_name"));
			searchItem.setId((String) solrDocument.get("id"));
			searchItem.setImage((String) solrDocument.get("item_image"));
			searchItem.setPrice((long) solrDocument.get("item_price"));
			searchItem.setSell_point((String) solrDocument.get("item_sell_point"));
			//取高亮結果
			List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
			String itemTitle = "";
			if (list != null && list.size() > 0) {
				itemTitle = list.get(0);
			} else {
				itemTitle = (String) solrDocument.get("item_title");
			}
			searchItem.setTitle(itemTitle);
			//添加到商品列表
			itemList.add(searchItem);
		}
		//把列表添加到返回結果對象中
		result.setItemList(itemList);
		return result;
	}
}

5.4.    Service層
需要有一個接口一個實現類,需要對外發布服務。
參數:String keyWord
      int page
      int rows
返回值:SearchResult
業務邏輯:
1)根據參數創建一個查詢條件對象。需要指定默認搜索域,還需要配置高亮顯示。
2)調用dao查詢。得到一個SearchResult對象
3)計算查詢總頁數,每頁顯示記錄數就是rows參數。

@Service
public class SearchServiceImpl implements SearchService {

	@Autowired
	private SearchDao searchDao;
	
	@Value("${DEFAULT_FIELD}")
	private String DEFAULT_FIELD;
	
	@Override
	public SearchResult search(String keyWord, int page, int rows) throws Exception {
		//創建一個SolrQuery對象
		SolrQuery query = new SolrQuery();
		//設置查詢條件
		query.setQuery(keyWord);
		//設置分頁條件
		query.setStart((page - 1) * rows);
		//設置rows
		query.setRows(rows);
		//設置默認搜索域
		query.set("df", DEFAULT_FIELD);
		//設置高亮顯示
		query.setHighlight(true);
		query.addHighlightField("item_title");
		query.setHighlightSimplePre("<em style=\"color:red\">");
		query.setHighlightSimplePost("</em>");
		//執行查詢
		SearchResult searchResult = searchDao.search(query);
		//計算總頁數
		int recourdCount = searchResult.getRecourdCount();
		int pages = recourdCount / rows;
		if (recourdCount % rows > 0) pages++;
		//設置到返回結果
		searchResult.setTotalPages(pages);
		return searchResult;
	}

}

5.4.1.    發佈服務

5.5.    表現層
5.5.1.    引用服務
在e3-search-web中添加接口依賴

Springmvc.xml

5.5.2.    Controller
請求的url:/search
請求的方法:GET
參數:
keyword:查詢條件
Page:頁碼。如果沒有此參數,需要給默認值1。
返回的結果:
使用jsp展示,返回邏輯視圖。

@Controller
public class SearchController {

	@Autowired
	private SearchService searchService;
	@Value("${PAGE_ROWS}")
	private Integer PAGE_ROWS;
	
	@RequestMapping("/search")
	public String search(String keyword,@RequestParam(defaultValue="1") Integer page, Model model) throws Exception {
		//需要轉碼
		keyword = new String(keyword.getBytes("iso8859-1"), "utf-8");
		//調用Service查詢商品信息 
		SearchResult result = searchService.search(keyword, page, PAGE_ROWS);
		//把結果傳遞給jsp頁面
		model.addAttribute("query", keyword);
		model.addAttribute("totalPages", result.getTotalPages());
		model.addAttribute("recourdCount", result.getRecourdCount());
		model.addAttribute("page", page);
		model.addAttribute("itemList", result.getItemList());
		//返回邏輯視圖
		return "search";
	}
	
}

最後這裏附上solr安裝包的地址:https://download.csdn.net/download/qq_25106373/12021084

和商城項目中使用solrj管理solr服務實現搜索功能的示例程序地址,需要時可以參考:https://download.csdn.net/download/qq_25106373/12021094

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章