JAVAEE——Solr:安裝及配置、后台管理索引庫、 使用SolrJ管理索引庫、仿京東的電商搜索案例實現


1 學習回顧

1、 Lucene  Apache開源的全文檢索的工具包 創建索引 查詢索引

2、 遇到問題? 文件名 及文件內容  順序掃描法  全文檢索

3、 什么是全文檢索? 這種先創建索引 再對索引進行搜索的過程叫全文檢索

4、 索引是什么? 非結構數據中提取一個數據、並重新組合的過程叫索引

5、 Lucene實現

6、 入門程序

磁盤文件為原始文件

創建索引

第一步:獲取文件

第二步:創建文檔對象

第三步:創建分析器

第四步:保存索引及文檔到索引庫

 

搜索索引

第一步:用戶接口(百度)

第二步:創建Query查詢對象(KV)域名:值

第三步:執行查詢

第四步:渲染

 

7、 分析器(中文分析器)

標准

中日韓

SmartChineseAnalyzer

IKAnalyzer(擴展、停止)

 

8、 使用IK分析器

第一步:導入IK.jar

第二步:復制ik.cfg.xml

第三步:復制stopword.dic  ext.dic

全放在classpath

 

9、 Lucene的維護

添加、刪除、修改、查詢

 

10、 高級查詢

第一個:全查詢 MatchAllDocsQuery

**

第二個:TermQuery 精准查詢

第三個:區間查詢(根據數值)L

第四個:組合查詢BooleadQuery 多個  AND OR NOT  Occur.MUST  MUST_NOT SHOULD

 

1. 學習計划

1、 電商搜索案例分析

2、 Solr的安裝及配置

a) Solr整合tomcat

b) Solr后台管理功能介紹

c) 配置中文分析器

 

solr在項目中的應用及電商搜索實現

3、     使用Solr的后台管理索引庫

d) 添加文檔

e) 刪除文檔

f) 修改文檔

g) 查詢文檔

4、 使用SolrJ管理索引庫

a) 添加文檔

b) 修改文檔

c) 刪除文檔

d) 查詢文檔

5、 電商搜索案例實現

a) 案例分析

b) 案例實現

 

 

 

2. 案例2:電商搜索

使用Solr實現電商網站中商品信息搜索功能,可以根據關鍵字、分類、價格搜索商品信息,也可以根據價格進行排序。

 

 

3. 需求分析

3.1. 實現方法

在一些大型門戶網站、電子商務網站等都需要站內搜索功能,使用傳統的數據庫查詢方式實現搜索無法滿足一些高級的搜索需求,比如:搜索速度要快、搜索結果按相關度排序、搜索內容格式不固定等,這里就需要使用全文檢索技術實現搜索功能。

3.1.1. 使用Lucene實現

單獨使用Lucene實現站內搜索需要開發的工作量較大,主要表現在:索引維護、索引性能優化、搜索性能優化等,因此不建議采用。

3.1.2. 使用solr實現

基於Solr實現站內搜索擴展性較好並且可以減少程序員的工作量,因為Solr提供了較為完備的搜索引擎解決方案,因此在門戶、論壇等系統中常用此方案。

 

3.2. 什么是solr

Solr Apache下的一個頂級開源項目,采用Java開發,它是基於Lucene的全文搜索服務器。Solr提供了比Lucene更為豐富的查詢語言,同時實現了可配置、可擴展,並對索引、搜索性能進行了優化。

Solr可以獨立運行,運行在JettyTomcat等這些Servlet容器中,Solr 索引的實現方法很簡單,用 POST 方法向 Solr 服務器發送一個描述 Field 及其內容的 XML 文檔,Solr根據xml文檔添加、刪除、更新索引 。Solr 搜索只需要發送 HTTP GET 請求,然后對 Solr 返回Xmljson等格式的查詢結果進行解析,組織頁面布局。Solr不提供構建UI的功能,Solr提供了一個管理界面,通過管理界面可以查詢Solr的配置和運行情況。

 

SolrLucene的區別:

Lucene是一個開放源代碼的全文檢索引擎工具包,它不是一個完整的全文檢索引擎,Lucene提供了完整的查詢引擎和索引引擎,目的是為軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者以Lucene為基礎構建全文檢索引擎。

 Solr的目標是打造一款企業級的搜索引擎系統,它是一個搜索引擎服務,可以獨立運行,通過Solr可以非常快速的構建企業的搜索引擎,通過Solr也可以高效的完成站內搜索功能。

 

 

 

4. Solr安裝及配置

4.1. Solr的下載

Solr官方網站(http://lucene.apache.org/solr/ )下載Solr4.10.3,根據Solr的運行環境,Linux下需要下載lucene-4.10.3.tgzwindows下需要下載lucene-4.10.3.zip

Solr使用指南可參考:https://wiki.apache.org/solr/FrontPage。

4.2. Solr的文件夾結構

solr-4.10.3.zip解壓:

 

 

 

binsolr的運行腳本

contribsolr的一些貢獻軟件/插件,用於增強solr的功能。

dist:該目錄包含build過程中產生的warjar文件,以及相關的依賴文件。

docssolrAPI文檔

examplesolr工程的例子目錄:

l example/solr:

該目錄是一個包含了默認配置信息的SolrCore目錄。

l example/multicore

該目錄包含了在Solrmulticore中設置的多個Core目錄。

l example/webapps:

    該目錄中包括一個solr.war,該war可作為solr的運行實例工程。

licensessolr相關的一些許可信息

4.3. 運行環境

solr 需要運行在一個Servlet容器中,Solr4.10.3要求jdk使用1.7以上,Solr默認提供Jettyjava寫的Servlet容器),本教程使用Tocmat作為Servlet容器,環境如下:

 

SolrSolr4.10.3

Jdkjdk1.7.0_72

Tomcatapache-tomcat-7.0.53

4.4. Solr整合tomcat

4.4.1. Solr HomeSolrCore

創建一個Solr home目錄,SolrHomeSolr運行的主目錄,目錄中包括了運行Solr實例所有的配置文件和數據文件,Solr實例就是SolrCore,一個SolrHome可以包括多個SolrCoreSolr實例),每個SolrCore提供單獨的搜索和索引服務。

 

example\solr是一個solr home目錄結構,如下:

 

 

 

上圖中collection1”是一個SolrCoreSolr實例)目錄 ,目錄內容如下所示:

 

 

 

說明:

collection1:叫做一個Solr運行實例SolrCoreSolrCore名稱不固定,一個solr運行實例對外單獨提供索引和搜索接口。

solrHome中可以創建多個solr運行實例SolrCore

一個solr的運行實例對應一個索引目錄。

confSolrCore的配置文件目錄 。

data目錄存放索引文件需要創建

 

4.4.2. 整合步驟

第一步:安裝tomcatD:\temp\apache-tomcat-7.0.53

第二步:把solrwar包復制到tomcat webapp目錄下。

\solr-4.10.3\dist\solr-4.10.3.war復制到D:\temp\apache-tomcat-7.0.53\webapps下。

改名為solr.war
第三步:solr.war解壓。使用壓縮工具解壓或者啟動tomcat自動解壓。解壓之后刪除solr.war

第四步:把\solr-4.10.3\example\lib\ext目錄下的所有的jar包添加到solr工程中

第五步:配置solrHomesolrCore

1)創建一個solrhome(存放solr所有配置文件的一個文件夾)。\solr-4.10.3\example\solr目錄就是一個標准的solrhome

2)\solr-4.10.3\example\solr文件夾復制到D:\temp\0108路徑下,改名為solrhome,改名不是必須的,是為了便於理解。

3)solrhome下有一個文件夾叫做collection1這就是一個solrcore。就是一個solr的實例。一個solrcore相當於mysql中一個數據庫。Solrcore之間是相互隔離。

  1. solrcore中有一個文件夾叫做conf,包含了索引solr實例的配置信息。
  2. conf文件夾下有一個solrconfig.xml。配置實例的相關信息。如果使用默認配置可以不用做任何修改。

Xml的配置信息:

Libsolr服務依賴的擴展包,默認的路徑是collection1\lib文件夾,如果沒有  就創建一個

dataDir配置了索引庫的存放路徑。默認路徑是collection1\data文件夾,如 果沒有data文件夾,會自動創建。

requestHandler

 

 

 

第六步:告訴solr服務器配置文件也就是solrHome的位置。修改web.xml使用jndi的方式告訴solr服務器。

Solr/home名稱必須是固定的。

 

 

第七步:啟動tomcat

第八步:訪問http://localhost:8080/solr/

 

4.5. Solr后台管理

4.5.1. 管理界面

 

 

4.5.2. Dashboard

儀表盤,顯示了該Solr實例開始啟動運行的時間、版本、系統資源、jvm等信息。

4.5.3. Logging

Solr運行日志信息

4.5.4. Cloud

CloudSolrCloud,即Solr雲(集群),當使用Solr Cloud模式運行時會顯示此菜單,如下圖是Solr Cloud的管理界面:

 

 

4.5.5. Core Admin

Solr Core的管理界面。Solr Core Solr的一個獨立運行實例單位,它可以對外提供索引和搜索服務,一個Solr工程可以運行多個SolrCoreSolr實例),一個Core對應一個索引目錄。

 

添加solrcore

第一步:復制collection1改名為collection2

第二步:修改core.propertiesname=collection2

第三步:重啟tomcat

4.5.6. java properties

SolrJVM 運行環境中的屬性信息,包括類路徑、文件編碼、jvm內存設置等信息。

 

4.5.7. Tread Dump

顯示Solr Server中當前活躍線程信息,同時也可以跟蹤線程運行棧信息。

4.5.8. Core selector

選擇一個SolrCore進行詳細操作,如下:

 

 

4.5.9. Analysis

 

 

通過此界面可以測試索引分析器和搜索分析器的執行情況。

4.5.10. Dataimport

可以定義數據導入處理器,從關系數據庫將數據導入 Solr索引庫中。

4.5.11. Document

通過此菜單可以創建索引、更新索引、刪除索引等操作,界面如下:

 

 

 

/update表示更新索引,solr默認根據id(唯一約束)域來更新Document的內容,如果根據id值搜索不到id域則會執行添加操作,如果找到則更新。

4.5.12. Query

 

 

 

通過/select執行搜索索引,必須指定“q”查詢條件方可搜索。

4.6. 配置中文分析器

4.6.1. Schema.xml

schema.xml,在SolrCoreconf目錄下,它是Solr數據表配置文件,它定義了加入索引的數據的數據類型的。主要包括FieldTypesFields和其他的一些缺省設置。

 

 

1.1.1.1 FieldType域類型定義

下邊text_general”是Solr默認提供的FieldType,通過它說明FieldType定義的內容:

 

 

 

FieldType子結點包括:name,class,positionIncrementGap等一些參數:

name:是這個FieldType的名稱

class:是Solr提供的包solr.TextFieldsolr.TextField 允許用戶通過分析器來定制索引和查詢,分析器包括一個分詞器(tokenizer)和多個過濾器(filter

positionIncrementGap:可選屬性,定義在同一個文檔中此類型數據的空白間隔,避免短語匹配錯誤,此值相當於Lucene的短語查詢設置slop值,根據經驗設置為100

 

FieldType定義的時候最重要的就是定義這個類型的數據在建立索引和進行查詢的時候要使用的分析器analyzer,包括分詞和過濾

 

索引分析器中:使用solr.StandardTokenizerFactory標准分詞器solr.StopFilterFactory停用詞過濾器solr.LowerCaseFilterFactory小寫過濾器。

搜索分析器中:使用solr.StandardTokenizerFactory標准分詞器,solr.StopFilterFactory停用詞過濾器,這里還用到了solr.SynonymFilterFactory同義詞過濾器。

1.1.1.2 Field定義

fields結點內定義具體的Fieldfiled定義包括name,type(為之前定義過的各種FieldType,indexed(是否被索引),stored(是否被儲存),multiValued(是否存儲多個值)等屬性。

如下:

<field name="name" type="text_general" indexed="true" stored="true"/>

<field name="features" type="text_general" indexed="true" stored="true" multiValued="true"/>

 

multiValued:該Field如果要存儲多個值時設置為truesolr允許一個Field存儲多個值,比如存儲一個用戶的好友id(多個),商品的圖片(多個,大圖和小圖),通過使用solr查詢要看出返回給客戶端是數組:

 

 

1.1.1.3 uniqueKey

Solr中默認定義唯一主鍵keyid域,如下:

 

 

 

Solr在刪除、更新索引時使用id域進行判斷,也可以自定義唯一主鍵。

注意在創建索引時必須指定唯一約束。

1.1.1.4 copyField復制域

copyField復制域,可以將多個Field復制到一個Field中,以便進行統一的檢索:

比如,輸入關鍵字搜索title標題內容content

定義titlecontenttext的域:

 

 

 

 

根據關鍵字只搜索text域的內容就相當於搜索titlecontent,將titlecontent復制到text中,如下:

 

 

1.1.1.5 dynamicField(動態字段)

動態字段就是不用指定具體的名稱,只要定義字段名稱的規則,例如定義一個 dynamicFieldname *_i,定義它的typetext,那么在使用這個字段的時候,任何以_i結尾的字段都被認為是符合這個定義的,例如:name_igender_ischool_i等。

 

自定義Field名為:product_title_tproduct_title_tscheam.xml中的dynamicField規則匹配成功,如下:

 

 

product_title_t”是以“_t”結尾。

 

創建索引:

 

 

 

搜索索引:

 

 

 

4.6.2. 安裝中文分詞器

使用IKAnalyzer中文分析器。

 

第一步:把IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目錄下。

第二步:復制IKAnalyzer的配置文件和自定義詞典和停用詞詞典到solrclasspath下。

第三步:在schema.xml中添加一個自定義的fieldType,使用中文分析器。

<!-- IKAnalyzer-->

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

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

    </fieldType>

 

第四步:定義field,指定fieldtype屬性為text_ik

<!--IKAnalyzer Field-->

   <field name="title_ik" type="text_ik" indexed="true" stored="true" />

   <field name="content_ik" type="text_ik" indexed="true" stored="false" multiValued="true"/>

 

第四步:重啟tomcat

測試:

 

 

4.7. 設置業務系統Field

如果不使用Solr提供的Field可以針對具體的業務需要自定義一套Field,如下是商品信息Field

 

<!--product-->
   <field name="product_name" type="text_ik" indexed="true" stored="true"/>
   <field name="product_price"  type="float" indexed="true" stored="true"/>
   <field name="product_description" type="text_ik" indexed="true" stored="false" />
   <field name="product_picture" type="string" indexed="false" stored="true" />
   <field name="product_catalog_name" type="string" indexed="true" stored="true" />

   <field name="product_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
   <copyField source="product_name" dest="product_keywords"/>
   <copyField source="product_description" dest="product_keywords"/>

 

5. Solr管理索引庫

a) 維護索引

5.1. 添加/更新文檔

添加或更新單個文檔

 

 

5.2. 批量導入數據

使用dataimport插件批量導入數據。

第一步:把dataimport插件依賴的jar包添加到solrcorecollection1\lib)中

 

還需要mysql的數據庫驅動。

第二步:配置solrconfig.xml文件,添加一個requestHandler

 <requestHandler name="/dataimport"

class="org.apache.solr.handler.dataimport.DataImportHandler">

    <lst name="defaults">

      <str name="config">data-config.xml</str>

     </lst>

  </requestHandler> 

 

第三步:創建一個data-config.xml,保存到collection1\conf\目錄下

<?xml version="1.0" encoding="UTF-8" ?>  

<dataConfig>   

<dataSource type="JdbcDataSource"   

    driver="com.mysql.jdbc.Driver"   

    url="jdbc:mysql://localhost:3306/lucene"   

    user="root"   

    password="root"/>   

<document>   

  <entity name="product" query="SELECT pid,name,catalog_name,price,description,picture FROM products ">

     <field column="pid" name="id"/>

     <field column="name" name="product_name"/>

     <field column="catalog_name" name="product_catalog_name"/>

     <field column="price" name="product_price"/>

     <field column="description" name="product_description"/>

     <field column="picture" name="product_picture"/>

  </entity>   

</document>   

 

</dataConfig>

 

第四步:重啟tomcat

 

 

第五步:點擊execute”按鈕導入數據

 

到入數據前會先清空索引庫,然后再導入。

 

5.3. 刪除文檔

刪除索引格式如下:

 

1) 刪除制定ID的索引

<delete>

  <id>8</id>

</delete>

<commit/>

2) 刪除查詢到的索引數據

<delete>

  <query>product_catalog_name:幽默雜貨</query>

</delete>

3) 刪除所有索引數據

 <delete>

  <query>*:*</query>

</delete>

b) 查詢索引

通過/select搜索索引,Solr制定一些參數完成不同需求的搜索:

 

1.q - 查詢字符串,必須的,如果查詢所有使用*:*

 

 

2.fq - filter query)過慮查詢,作用:在q查詢符合結果中同時是fq查詢符合的,例如::

 

 

過濾查詢價格從120的記錄。

也可以在q”查詢條件中使用product_price:[1 TO 20],如下:

 

也可以使用*”表示無限,例如:

20以上:product_price:[20 TO *]

20以下:product_price:[* TO 20]

 

3.sort - 排序,格式:sort=<field name>+<desc|asc>[,<field name>+<desc|asc>]… 。示例:

按價格降序

 

4.start - 分頁顯示使用,開始記錄下標,從0開始

5.rows - 指定返回結果最多有多少條記錄,配合start來實現分頁。

 

 

顯示前10條。

 

6.fl - 指定返回那些字段內容,用逗號或空格分隔多個。

 

 

顯示商品圖片、商品名稱、商品價格

 

7.df-指定一個搜索Field

 

 

也可以在SolrCore目錄 中conf/solrconfig.xml文件中指定默認搜索Field,指定后就可以直接在“q”查詢條件中輸入關鍵字。

 

 

 

 

8.wt - (writer type)指定輸出格式,可以有 xml, json, php, phps, 后面 solr 1.3增加的,要用通知我們,因為默認沒有打開。

 

9.hl 是否高亮 ,設置高亮Field,設置格式前綴和后綴。

 

 

 

 

6. 使用SolrJ管理索引庫

a) 什么是solrJ

solrj是訪問Solr服務的java客戶端,提供索引和搜索的請求方法,SolrJ通常在嵌入在業務系統中,通過SolrJAPI接口操作Solr服務,如下圖:

 

 

 

b) 依賴的jar

 

 

 

c) 添加文檔

1.c.1. 實現步驟

第一步:創建一個java工程

第二步:導入jar包。包括solrJjar包。還需要

 

 

第三步:和Solr服務器建立連接。HttpSolrServer對象建立連接。

第四步:創建一個SolrInputDocument對象,然后添加域。

第五步:將SolrInputDocument添加到索引庫。

第六步:提交。

1.c.2. 代碼實現

//向索引庫中添加索引
    @Test
    public void addDocument() throws Exception {
        //和solr服務器創建連接
        //參數:solr服務器的地址
        SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
        //創建一個文檔對象
        SolrInputDocument document = new SolrInputDocument();
        //向文檔中添加域
        //第一個參數:域的名稱,域的名稱必須是在schema.xml中定義的
        //第二個參數:域的值
        document.addField("id", "c0001");
        document.addField("title_ik", "使用solrJ添加的文檔");
        document.addField("content_ik", "文檔的內容");
        document.addField("product_name", "商品名稱");
        //把document對象添加到索引庫中
        solrServer.add(document);
        //提交修改
        solrServer.commit();
        
    }

 


d) 
刪除文檔 

1.d.1. 根據id刪除

//刪除文檔,根據id刪除
    @Test
    public void deleteDocumentByid() throws Exception {
        //創建連接
        SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
        //根據id刪除文檔
        solrServer.deleteById("c0001");
        //提交修改
        solrServer.commit();
    }

 


1.d.2. 
根據查詢刪除 

查詢語法完全支持Lucene的查詢語法。

  

//根據查詢條件刪除文檔
    @Test
    public void deleteDocumentByQuery() throws Exception {
        //創建連接
        SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
        //根據查詢條件刪除文檔
        solrServer.deleteByQuery("*:*");
        //提交修改
        solrServer.commit();
    }

 

e) 修改文檔

solrJ中修改沒有對應的update方法,只有add方法,只需要添加一條新的文檔,和被修改的文檔id一致就,可以修改了。本質上就是先刪除后添加。

 

f) 查詢文檔

1.f.1. 簡單查詢

//查詢索引
    @Test
    public void queryIndex() throws Exception {
        //創建連接
        SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
        //創建一個query對象
        SolrQuery query = new SolrQuery();
        //設置查詢條件
        query.setQuery("*:*");
        //執行查詢
        QueryResponse queryResponse = solrServer.query(query);
        //取查詢結果
        SolrDocumentList solrDocumentList = queryResponse.getResults();
        //共查詢到商品數量
        System.out.println("共查詢到商品數量:" + solrDocumentList.getNumFound());
        //遍歷查詢的結果
        for (SolrDocument solrDocument : solrDocumentList) {
            System.out.println(solrDocument.get("id"));
            System.out.println(solrDocument.get("product_name"));
            System.out.println(solrDocument.get("product_price"));
            System.out.println(solrDocument.get("product_catalog_name"));
            System.out.println(solrDocument.get("product_picture"));
            
        }
    }

 


1.f.2. 
復雜查詢 

其中包含查詢、過濾、分頁、排序、高亮顯示等處理。

//復雜查詢索引
    @Test
    public void queryIndex2() throws Exception {
        //創建連接
        SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
        //創建一個query對象
        SolrQuery query = new SolrQuery();
        //設置查詢條件
        query.setQuery("鑽石");
        //過濾條件
        query.setFilterQueries("product_catalog_name:幽默雜貨");
        //排序條件
        query.setSort("product_price", ORDER.asc);
        //分頁處理
        query.setStart(0);
        query.setRows(10);
        //結果中域的列表
        query.setFields("id","product_name","product_price","product_catalog_name","product_picture");
        //設置默認搜索域
        query.set("df", "product_keywords");
        //高亮顯示
        query.setHighlight(true);
        //高亮顯示的域
        query.addHighlightField("product_name");
        //高亮顯示的前綴
        query.setHighlightSimplePre("<em>");
        //高亮顯示的后綴
        query.setHighlightSimplePost("</em>");
        //執行查詢
        QueryResponse queryResponse = solrServer.query(query);
        //取查詢結果
        SolrDocumentList solrDocumentList = queryResponse.getResults();
        //共查詢到商品數量
        System.out.println("共查詢到商品數量:" + solrDocumentList.getNumFound());
        //遍歷查詢的結果
        for (SolrDocument solrDocument : solrDocumentList) {
            System.out.println(solrDocument.get("id"));
            //取高亮顯示
            String productName = "";
            Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
            List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");
            //判斷是否有高亮內容
            if (null != list) {
                productName = list.get(0);
            } else {
                productName = (String) solrDocument.get("product_name");
            }
            
            System.out.println(productName);
            System.out.println(solrDocument.get("product_price"));
            System.out.println(solrDocument.get("product_catalog_name"));
            System.out.println(solrDocument.get("product_picture"));
            
        }
    }

 


7. 
案例實現 

a) 原型分析

 

 

b) 系統架構

 

 

c) 工程搭建

創建一個web工程導入jar

1、springmvc的相關jar

2、solrJjar

3、Example\lib\ext下的jar

 

7.0.1. springmvc.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.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-4.0.xsd">
        
    <context:component-scan base-package="com.itheima.jd"/>
    <!-- 配置注解驅動,如果配置此標簽可以不用配置處理器映射器和適配器 -->
    <mvc:annotation-driven/>
        <!-- 配置視圖解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- SolrServer的配置 -->
    <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
        <constructor-arg index="0" value="http://localhost:8080/solr"/>
    </bean>
</beans>

 


7.0.2. 
web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>solr-jd</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- 配置前端控制器 -->
  <servlet>
      <servlet-name>springmvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <!-- 指定springmvc配置文件的路徑 
              如果不指定默認為:/WEB-INF/${servlet-name}-servlet.xml
          -->
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:springmvc.xml</param-value>
      </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>springmvc</servlet-name>
      <url-pattern>*.action</url-pattern>
  </servlet-mapping>
  <!-- 解決post亂碼問題 -->
  <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

 


  

 

d) Dao

功能:接收service層傳遞過來的參數,根據參數查詢索引庫,返回查詢結果。

參數:SolrQuery對象

返回值:一個商品列表List<ProductModel>

方法定義:public List<ProductModel> getResultModelFromSolr(QueryVo vo) throws Exception;

 

 

商品對象模型:

public class ProductModel {
    // 商品編號
    private String pid;
    // 商品名稱
    private String name;
    // 商品分類名稱
    private String catalog_name;
    // 價格
    private float price;
    // 商品描述
    private String description;
    // 圖片名稱
    private String picture;
}

 

@Repository
public class SolrDaoImpl implements SolrDao {
    @Autowired
    private SolrServer solrServer;
    
    public List<ProductModel> getResultModelFromSolr(QueryVo vo) throws Exception{
        SolrQuery solrQuery = new SolrQuery();
        //關鍵詞
        if(null != vo.getQueryString() && !"".equals(vo.getQueryString())){
            solrQuery.setQuery(vo.getQueryString());
            solrQuery.set("df", "product_keywords");
            
        }
        //商品類型
        if(null != vo.getCatalog_name() && !"".equals(vo.getCatalog_name().trim())){
            solrQuery.addFilterQuery("product_catalog_name:" + vo.getCatalog_name());
        }
        //價格
        if(null != vo.getPrice() && !"".equals(vo.getPrice().trim())){
            String[] split = vo.getPrice().split("-");
            if(split.length == 2){
                solrQuery.addFilterQuery("product_price:[" + split[0] + " TO " + split[1] + "]");
            }else{
                solrQuery.addFilterQuery("product_price:[" + split[0] + " TO *]");
            }
        }
        //價格排序
        if("1".equals(vo.getSort())){
            solrQuery.setSort("product_price", ORDER.desc);
        }else{
            solrQuery.setSort("product_price", ORDER.asc);
        }
        
        //顯示的域
        //solrQuery.setFields("id,product_name,product_price");
        
        //1:設置高亮開關
        solrQuery.setHighlight(true);
        //2:需要高亮的域
        solrQuery.addHighlightField("product_name");
        //3:高亮的簡單樣式  前綴
        solrQuery.setHighlightSimplePre("<span style='color:red'>");
        //4:高亮的簡單樣式 后綴
        solrQuery.setHighlightSimplePost("</span>");
        QueryResponse response = solrServer.query(solrQuery);
        //取出高亮
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
    
        //取出結果集
        SolrDocumentList docs = response.getResults();
        //打印總條數
        System.out.println("總條數:" + docs.getNumFound());
        //結果集
        List<ProductModel> productModels = new ArrayList<ProductModel>();
        //閬嶅巻
        for (SolrDocument doc : docs) {
            
            ProductModel productModel = new ProductModel();
            //ID
            String id = (String) doc.get("id");
            productModel.setPid(id);
            //
            Map<String, List<String>> map = highlighting.get(id);
            List<String> list = map.get("product_name");
            //判斷高亮必須不為空
            if(null != list && list.size() > 0){
                String name = list.get(0);
                productModel.setName(name);
            }
            //價格
            productModel.setPrice((float) doc.get("product_price"));
            //商品圖片
            productModel.setPicture((String) doc.get("product_picture"));
            //商品類型
            productModel.setCatalog_name((String) doc.get("product_catalog_name"));
            
            productModels.add(productModel);
        }
        return productModels;
    }
    
}

 

 


e) 
Service 

功能:接收action傳遞過來的參數,根據參數拼裝一個查詢條件,調用dao層方法,查詢商品列表。接收返回的商品列表和商品的總數量,根據每頁顯示的商品數量計算總頁數。

參數:

1、查詢條件:字符串

2、商品分類的過濾條件:商品的分類名稱,字符串

3、商品價格區間:傳遞一個字符串,滿足格式:“0-100101-200201-*

4、排序條件:頁面傳遞過來一個升序或者降序就可以,默認是價格排序。0:升序1:降序

5、分頁信息:每頁顯示的記錄條數創建一個常量60條。傳遞一個當前頁碼就可以了。

業務邏輯

1、根據參數創建查詢對象

2、調用dao執行查詢。

3、根據總記錄數計算總頁數。

返回值:ResultModel

 

方法定義:ResultModel queryProduct(String queryString, String caltalog_name, String price, String sort, Integer page) throws Exception;

@Service
public class SolrServiceImpl implements SolrService {

    
    @Autowired
    private SolrDao solrDao;
    public List<ProductModel> getResultModelFromSolr(QueryVo vo) throws Exception {
        return solrDao.getResultModelFromSolr(vo);
    }

}

 


f) 
controller 

功能:接收頁面傳遞過來的參數調用service查詢商品列表。將查詢結果返回給jsp頁面,還需要查詢參數的回顯。

 

參數:

1、查詢條件:字符串

2、商品分類的過濾條件:商品的分類名稱,字符串

3、商品價格區間:傳遞一個字符串,滿足格式:“0-100101-200201-*

4、排序條件:頁面傳遞過來一個升序或者降序就可以,默認是價格排序。0:升序1:降序

5、分頁信息:每頁顯示的記錄條數創建一個常量60條。傳遞一個當前頁碼就可以了。

6Model:相當於request

 

返回結果:String類型,就是一個jsp的名稱。

 

public class QueryVo {

 

//關鍵詞

private String queryString;

//過濾條件 商品類型

//價格區間

private String catalog_name;

private String price;

//排序  1 正   0

private String sort;

 

/**
 * 商品搜索
 * @author lx
 *
 */
@Controller
public class ProductController {

    @Autowired
    SolrService solrService;
    //搜索
    @RequestMapping("/list.action")
    public String list(QueryVo vo,Model model) throws Exception{
        //結果集
        List<ProductModel> productList = solrService.getResultModelFromSolr(vo);
        model.addAttribute("productList", productList);
        model.addAttribute("catalog_name", vo.getCatalog_name());
        model.addAttribute("price", vo.getPrice());
        model.addAttribute("sort", vo.getSort());
        model.addAttribute("queryString", vo.getQueryString());
        return "product_list";
    }
}

 

g) Jsp 

參考資料。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM