1. 程式人生 > >SSM綜合專案實戰(TTSC) -- day09 Solr,搜尋系統

SSM綜合專案實戰(TTSC) -- day09 Solr,搜尋系統

一、solr服務的安裝

1、為什麼要使用solr服務

我們需要實現商品的查詢功能,可以使用MySQL進行查詢,但是MySQL的模糊查詢(like)速度很慢,而且資料量越大,查詢速度就越慢。

所以資料量大的時候不會使用MySQL實現搜尋功能,我們這裡使用solr實現搜尋功能。

2、安裝solr

安裝詳見:http://blog.csdn.net/wingzhezhe/article/details/73368610

3、設定使用域名進行訪問

(1)、使用switchhost修改host檔案


(2)、修改nginx.conf配置檔案


4、最終測試效果


二、Solr配置和使用

1、配置IK分詞器

(1)、上傳jar包到 solr/WEB-INF/lib 下面



(2)、上傳核心配置檔案和停止詞擴充套件次配置檔案到 solr/WEB-INF/classes 資料夾下



(3)、在 solrHome/collection1/conf/schema.xml 加入一下配置,使IK分詞器生效

	<!-- IKAnalyzer-->
	<fieldType name="text_ik" class="solr.TextField">
		<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
	</fieldType>

	<!--IKAnalyzer Field-->
	<field name="content_ik" type="text_ik" indexed="true" stored="true" /> 


(4)、瀏覽器測試IK分詞器


2、業務域的配置

(1)、在 sorlHome/collection1/conf/schema.xml中配置搜尋商品的業務域欄位

	<!-- 為收縮商品配置業務域 indexed="true":表示需要索引 stored="true":表示需要儲存-->
	<!-- title欄位需要儲存索引以及分詞 -->
	<field name="item_title" type="text_ik" indexed="true" stored="true" />
	<!-- price欄位需要儲存索引不需要分詞 -->
	<field name="item_price" type="long" indexed="true" stored="true" />
	<!-- image欄位不需要索引和分詞,但是需要儲存 -->
	<field name="item_image" type="string" indexed="false" stored="true" />
	<!-- cid欄位需要儲存,但不需要索引以及分詞 -->
	<field name="item_cid" type="long" indexed="false" stored="true" />
	<!-- status欄位需要索引,但是不需要儲存以及分詞 -->
	<field name="item_status" type="int" indexed="true" stored="false" />


(2)、重啟tomcat,檢視業務域是否生效


3、回顧solrJ的使用

(1)、建立打包方式為jar包的maven工程,繼承taotao-parent


(2)、建立單機版的solr操作的測試類

package cn.itcast.solr;

import java.util.List;
import java.util.Map;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;

/**
 * 單機版solr測試類
 * 
 * @author Administrator
 *
 */
public class SolrTest {

	// 宣告連線物件
	private HttpSolrServer solrServer;

	@Before
	public void init() {
		// 宣告介面地址
		String baseUrl = "http://solr.taotao.com/solr";

		this.solrServer = new HttpSolrServer(baseUrl);
	}

	/**
	 * 測試新增和更新
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSaveAndUpdate() throws Exception {
		// 建立solrInputDocument物件,用來存放資料
		SolrInputDocument doc = new SolrInputDocument();

		// 設定唯一域id,如果id不存在,則執行新增,如果id存在,則執行更新
		doc.addField("id", "id_007");
		doc.addField("item_title", "第七次向solr索引中新增資料");

		// 使用solrServler連線物件執行操作
		this.solrServer.add(doc);

		// 提交事務
		this.solrServer.commit();
	}

	/**
	 * 刪除索引庫
	 * 
	 * @throws Exception
	 */
	@Test
	public void testDelete() throws Exception {
		// 使用id刪除
		this.solrServer.deleteById("id_001");

		// 刪除全部(慎用)
		this.solrServer.deleteByQuery("*:*");

		// 提交事務
		this.solrServer.commit();
	}

	@Test
	public void testQuery() throws Exception {
		// 建立查詢物件
		SolrQuery solrQuery = new SolrQuery();

		// 設定查詢語句
		solrQuery.setQuery("item_title:solr");

		// 設定分頁資料
		solrQuery.setStart(0);
		solrQuery.setRows(5);

		// 設定高亮資料
		// 設定開啟高亮
		solrQuery.setHighlight(true);
		// 設定高亮欄位
		solrQuery.addHighlightField("item_title");
		// 設定高亮的字首
		solrQuery.setHighlightSimplePre("<font color='red'>");
		// 設定高粱的字尾
		solrQuery.setHighlightSimplePost("</font>");

		// 發起請求,獲取response
		QueryResponse response = this.solrServer.query(solrQuery);

		// 獲取高亮資料,高亮資料查出來的格式如下
		// {
		// "s0001": {"item_title": ["今天開始使用<em>solr</em>"]},
		// "s0002": {"item_title": ["今天開始使用<em>solr</em>實"]}
		// }
		Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

		// 從response中獲取結果集
		SolrDocumentList solrDocumentList = response.getResults();

		// 列印查詢的資料條數
		System.out.println("查詢到的結果條數是:" + solrDocumentList.getNumFound());

		// 解析結果集,列印
		for (SolrDocument solrDocument : solrDocumentList) {
			// 獲取高亮資料
			List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");

			System.out.println("-----------------------------------------");

			// 列印id
			System.out.println(solrDocument.get("id"));
			// 列印item_title
			System.out.println(solrDocument.get("item_title"));

			// 列印高亮欄位
			if (list != null && list.size() > 0) {
				System.out.println(list.get(0));
			}
		}
	}

}

三、Solr叢集版

1、叢集版安裝

http://blog.csdn.net/wingzhezhe/article/details/73456885

2、測試solrJ連線叢集

package cn.itcast.solr;

import java.util.List;
import java.util.Map;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;

/**
 * 測試solr叢集版連線
 * 
 * @author Administrator
 *
 */
public class SolrCloudTest {

	// 宣告連線物件
	private CloudSolrServer cloudSolrServer;

	@Before
	public void init() {
		// 宣告zookeeper的地址
		String zkHost = "192.168.37.161:2281,192.168.37.161:2281,192.168.37.161:2381";

		this.cloudSolrServer = new CloudSolrServer(zkHost);

		// 設定索引庫的名字
		this.cloudSolrServer.setDefaultCollection("collection2");
	}

	/**
	 * 測試新增和更新
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSaveAndUpdate() throws Exception {
		// 建立solrInputDocument物件,用來存放資料
		SolrInputDocument doc = new SolrInputDocument();

		// 設定唯一域id,如果id不存在,則執行新增,如果id存在,則執行更新
		doc.addField("id", "id_009");
		doc.addField("item_title", "第七次向solr索引中新增資料");

		// 使用solrServler連線物件執行操作
		this.cloudSolrServer.add(doc);

		// 提交事務
		this.cloudSolrServer.commit();
	}

	/**
	 * 刪除索引庫
	 * 
	 * @throws Exception
	 */
	@Test
	public void testDelete() throws Exception {
		// 使用id刪除
		this.cloudSolrServer.deleteById("id_008");

		// 刪除全部(慎用)
		//this.cloudSolrServer.deleteByQuery("*:*");

		// 提交事務
		this.cloudSolrServer.commit();
	}

	@Test
	public void testQuery() throws Exception {
		// 建立查詢物件
		SolrQuery solrQuery = new SolrQuery();

		// 設定查詢語句
		solrQuery.setQuery("item_title:solr");

		// 設定分頁資料
		solrQuery.setStart(0);
		solrQuery.setRows(5);

		// 設定高亮資料
		// 設定開啟高亮
		solrQuery.setHighlight(true);
		// 設定高亮欄位
		solrQuery.addHighlightField("item_title");
		// 設定高亮的字首
		solrQuery.setHighlightSimplePre("<font color='red'>");
		// 設定高粱的字尾
		solrQuery.setHighlightSimplePost("</font>");

		// 發起請求,獲取response
		QueryResponse response = this.cloudSolrServer.query(solrQuery);

		// 獲取高亮資料,高亮資料查出來的格式如下
		// {
		// "s0001": {"item_title": ["今天開始使用<em>solr</em>"]},
		// "s0002": {"item_title": ["今天開始使用<em>solr</em>實"]}
		// }
		Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

		// 從response中獲取結果集
		SolrDocumentList solrDocumentList = response.getResults();

		// 列印查詢的資料條數
		System.out.println("查詢到的結果條數是:" + solrDocumentList.getNumFound());

		// 解析結果集,列印
		for (SolrDocument solrDocument : solrDocumentList) {
			// 獲取高亮資料
			List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");

			System.out.println("-----------------------------------------");

			// 列印id
			System.out.println(solrDocument.get("id"));
			// 列印item_title
			System.out.println(solrDocument.get("item_title"));

			// 列印高亮欄位
			if (list != null && list.size() > 0) {
				System.out.println(list.get(0));
			}
		}
	}
}

四、建立搜尋系統

1、架構分析


2、建立服務層


(1)、建立聚合父工程 taotao-search



(2)、建立父工程的子模組 taotao-search-interface、taotao-search-service




(3)、加入專案之間的依賴關係

taotao-search-interface                依賴              taotao-manager-pojo

taotao-search-service                  依賴              taotao-manager-mapper     和      taotao-search-interface        

(4)、加入tomcat外掛


(5)、加入配置檔案

注意:配置檔案按照taotao-manager-service拷貝加入,改名,刪除redis的配置,新增solr的配置


env.properties

#配置solr單機版的url
solr.baseURL=http://solr.taotao.com/solr/

#配置solr叢集版的連線地址
cloud.zkHost=192.168.37.161:2281,192.168.37.161:2281,192.168.37.161:2381

#配置solr叢集版索引庫的名字
cloud.colleciton=collection2

applicationContext-solr.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd  
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd  
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">


	<!-- 配置單機版solr -->
	<bean class="org.apache.solr.client.solrj.impl.HttpSolrServer">
		<!-- 配置單機版的solr連線地址 -->
		<constructor-arg name="baseURL" value="${solr.baseURL}" />
	</bean>

	<!-- 配置叢集版solr服務 -->
	<bean class="org.apache.solr.client.solrj.impl.CloudSolrServer">
		<!-- 配置zookeeper的叢集地址 -->
		<constructor-arg name="zkHost" value="${cloud.zkHost}" />
		<!-- 配置索引庫名字 -->
		<porperty name="defaultCollection" value="${cloud.colleciton}" />
	</bean>

</beans>  

3、建立表現層

(1)、建立獨立的maven工程 taotao-search-web


(2)、加入依賴關係

taotao-search-web                依賴                taotao-search-interface

(3)、加入tomcat外掛


(3)、加入配置檔案

注意:taotao-search-web配置檔案參考taotao-portal進行配置


4、加入搜尋系統的靜態資原始檔


5、配置域名訪問

(1)、修改host檔案


(2)、修改nginx.xml配置檔案


五、資料準備

1、匯入資料庫表


注意:由於之前已經在資料庫中匯入了tb_item和tb_item_desc表,需要先刪除,然後將tb_item_jd修改為tb_item表,將tb_item_jd_desc修改為tb_item_desc表

2、使用nginx的虛擬主機功能搭建圖片伺服器

(1)、將資料中的圖片資源解壓到無中文無空格的目錄下



(2)、使用switchhost配置host檔案中的圖片伺服器域名


(3)、在nginx.xml配置檔案中配置圖片伺服器地址


3、重啟nginx,啟動專案,測試執行


4、將資料庫中的商品資料匯入到solr索引庫中

(1)、在taotao-search-service專案中編寫程式碼匯入資料


package com.taotao.search.test;

import java.util.ArrayList;
import java.util.List;

import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.github.pagehelper.PageHelper;
import com.taotao.manager.mapper.ItemMapper;
import com.taotao.manager.pojo.Item;

/**
 * 將商品資料匯入到solr索引庫
 * 
 * @author Administrator
 *
 */
public class Item2SolrTest {

	// 叢集連線物件
	private CloudSolrServer cloudSolrServer;

	// 商品Mapper
	private ItemMapper itemMapper;

	@Before
	public void init() {
		// 獲取spring容器
		ApplicationContext app = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml");

		// 從容器中獲取連線物件和Mapper
		this.cloudSolrServer = app.getBean(CloudSolrServer.class);

		this.itemMapper = app.getBean(ItemMapper.class);
	}

	/**
	 * 將資料庫中的商品資訊匯入solr索引庫
	 * 
	 * @throws Exception
	 */
	//@Ignore //該註解目的是不執行test測試類
	@Test
	public void mysql2Solr() throws Exception {
		
		// 從MySQL中查詢出商品資料,可以使用ItemMapper查詢
		// 一次查詢所有資料可能會造成記憶體溢位,需要分頁查詢
		int page = 1;
		int pageSize = 0;
		do {
			// 設定分頁資料
			PageHelper.startPage(page, 500);
			// 執行查詢
			List<Item> list = this.itemMapper.select(null);

			// 宣告存放SolrInputDocument的容器
			List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();

			// 遍歷結果集,向solr索引庫中新增資料
			for (Item item : list) {
				// 把商品資料封裝到SolrInputDocument中
				SolrInputDocument doc = new SolrInputDocument();

				// 商品id
				doc.addField("id", item.getId());
				// 商品item_title
				doc.addField("item_title", item.getTitle());
				// 商品item_price
				doc.addField("item_price", item.getPrice());
				// 商品item_image
				doc.addField("item_image", item.getImage());
				// 商品item_cid
				doc.addField("item_cid", item.getCid());
				// 商品item_status
				doc.addField("item_status", item.getStatus());

				docs.add(doc);
			}

			// 使用CloudSolrServer連線物件將資料儲存到solr索引庫中
			this.cloudSolrServer.add(docs);
			// 提交
			this.cloudSolrServer.commit();
			
			page ++;
			//獲取查詢到的資料條數
			pageSize = list.size();
		} while (pageSize == 500);
	
	}
}

(2)、執行測試類,訪問solr叢集