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叢集