04_Solr的入門與使用

1. solr介紹

solr是apache開(kāi)源項(xiàng)目绒净,基于lucene,并默認(rèn)運(yùn)行在jetty這個(gè)serlvet容器中的優(yōu)秀的全文檢索服務(wù)器缤言〉ㄏ簦可通過(guò)http請(qǐng)求實(shí)現(xiàn)索引和搜索功能。

solr 和lucene區(qū)別
lucene是一個(gè)全文檢索的工具包蚌吸,不能夠進(jìn)行獨(dú)立的部署,對(duì)外提供服務(wù)佩微,必須嵌入到系統(tǒng)中跌造,高度耦合依托于系統(tǒng),并提供搜索服務(wù)。
solr 是一個(gè)全文檢索的搜索引擎(服務(wù)器/軟件系統(tǒng))互纯,能夠獨(dú)立部署留潦,可以對(duì)外單獨(dú)提供搜索服務(wù)殖卑。
solr 可以降低耦合度,lucene不可以菩鲜。

下載地址:
    Solr官方網(wǎng)站:
    http://lucene.apache.org/solr/ 
    下載地址:
    http://archive.apache.org/dist/lucene/solr/

解壓后的目錄結(jié)構(gòu):

1.png

example下的目錄結(jié)構(gòu):

2.png

1. tomcat整合solr運(yùn)行

第一步:解壓

1. 在D盤新建一個(gè)文件夾solr,將一個(gè)新的tomcat與solr工程解壓到該文件夾
3.png
2. 在解壓后的solr-4.10.3\example\webapps目錄下拷貝solr.war到tomcat的webapp目錄下解壓,為方便統(tǒng)一管理,解壓到solr的文件夾狮崩。解壓完畢刪除war包
4.png

第二步:拷貝jar包

3. 拷貝D:\solr\solr-4.10.3\example\lib\ext下的所有jar包到D:\solr\apache-tomcat-7.0.52\webapps\solr\WEB-INF\lib目錄下

第三步:solrhome

4. 在solr目錄下新建文件夾solrhome董习。
    概念:SolrHome是Solr運(yùn)行的主目錄皿淋,目錄中包括了運(yùn)行Solr實(shí)例所有的配置文件和數(shù)據(jù)文件,Solr實(shí)例就是SolrCore哑舒。example\solr下就是一個(gè)solr home目錄結(jié)構(gòu)。

拷貝D:\solr\solr-4.10.3\example\solr下的所有目錄到D:\solr\solrhome下膘滨,完成一個(gè)solrCore的創(chuàng)建〔桑可以在該目錄下創(chuàng)建多個(gè)實(shí)例
5.png
5. 最后,修改D:\solr\apache-tomcat-7.0.52\webapps\solr\WEB-INF,告訴它solrhome的位置
6.png
到D:\solr\apache-tomcat-7.0.52\bin中啟動(dòng)tomcat,訪問(wèn)http://localhost:8080/solr,能夠成功訪問(wèn)代表搭建成功
7.png
如果默認(rèn)開(kāi)啟的tomcat不是當(dāng)前路徑下的tomcat,刪除環(huán)境變量里的CATALINA_HOME的配置
1.1 新建solrcore
添加solrcore:
第一步:在D:\solr\solrhome復(fù)制collection1改名為collection2
第二步:修改core.properties北滥。設(shè)置name=collection2
第三步:重啟tomcat 
1.2 使用IKAnalyzer中文分析器。
第一步:把IKAnalyzer2012FF_u1.jar添加到tomcat中的solr/WEB-INF/lib目錄下

第二步:復(fù)制IKAnalyzer的配置文件和自定義詞典和停用詞詞典到solr項(xiàng)目的classpath下。
        在WEB-INF下如果沒(méi)有classes 需要?jiǎng)?chuàng)建一個(gè)司训。
8.png
第三步:在schema.xml中添加一個(gè)自定義的fieldType,使用中文分析器统扳。
<!-- IKAnalyzer-->
<fieldType name="text_ik" class="solr.TextField">
  <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>

第四步:定義field,指定field的type屬性為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,在analyze下輸入中文進(jìn)行測(cè)試
9.png

2. Solr管理索引庫(kù)

2.1 維護(hù)索引
1. 添加單個(gè)文檔(略)
2. 批量導(dǎo)入數(shù)據(jù)
    使用dataimport插件批量導(dǎo)入數(shù)據(jù)朱嘴。如果collection1下沒(méi)有l(wèi)ib  需要自己創(chuàng)建一個(gè)舌劳。

第一步:在D:\solr\solr-4.10.3\dist目錄下把dataimport插件依賴的jar包添加到solrcore(collection1\lib)中,沒(méi)有目錄就新建目錄

因?yàn)橐扛鶕?jù)數(shù)據(jù)庫(kù)的數(shù)據(jù)創(chuàng)建索引,因此還需要導(dǎo)入數(shù)據(jù)庫(kù)驅(qū)動(dòng)
11.png
第二步:配置collection1\conf\下的solrconfig.xml文件甚淡,添加一個(gè)requestHandler。
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
  <str name="config">data-config.xml</str>
 </lst>
</requestHandler> 

第三步:在同級(jí)目錄下創(chuàng)建一個(gè)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/solr"   
          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>


3. 上面name對(duì)應(yīng)的是field域,自定義的域要自己在schema.xml中配置
如果不使用Solr提供的Field可以針對(duì)具體的業(yè)務(wù)需要自定義一套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"/>

4. 重啟tomcat,完成批量索引的創(chuàng)建
12.png
2.2 刪除文檔
刪除索引格式如下:

1) 刪除指定ID的索引 
<delete>
    <id>8</id>
</delete>
需要加上
<commit />

2) 刪除查詢到的索引數(shù)據(jù) 
<delete>
    <query>product_catalog_name:幽默雜貨</query>
</delete>
<commit />

3) 刪除所有索引數(shù)據(jù)
 <delete>
    <query>*:*</query>
</delete>
<commit />
2.3 查詢索引
通過(guò)/select搜索索引,Solr制定一些參數(shù)完成不同需求的搜索:

1. q - 查詢字符串峻呕,必須的利职,如果查詢所有使用*:*。
2. fq - (filter query)過(guò)慮查詢瘦癌,作用:在q查詢符合結(jié)果中同時(shí)是fq查詢符合的
    也可以在“q”查詢條件中使用product_price:[1 TO 20]
    也可以使用“*”表示無(wú)限猪贪,例如:
    20以上:product_price:[20 TO *]
    20以下:product_price:[* TO 20]
13.png
3. sort - 排序
    product_price desc/asc

4. start - 分頁(yè)顯示使用,開(kāi)始記錄下標(biāo)讯私,從0開(kāi)始
5. rows - 指定返回結(jié)果最多有多少條記錄哮伟,配合start來(lái)實(shí)現(xiàn)分頁(yè)抡驼。

6. fl - 指定返回那些字段內(nèi)容馏锡,用逗號(hào)或空格分隔多個(gè)
7. df-指定一個(gè)默認(rèn)搜索Field
8. wt - (writer type)指定輸出格式霜医,可以有 xml, json, php, phps,
9. hl 是否高亮 ,設(shè)置高亮Field,設(shè)置格式前綴和后綴

3. 使用soloJ管理索引庫(kù)

solrj是訪問(wèn)Solr服務(wù)的java客戶端丰辣,提供索引和搜索的請(qǐng)求方法琐凭,SolrJ通常在嵌入在業(yè)務(wù)系統(tǒng)中孽拷,通過(guò)SolrJ的API接口操作Solr服務(wù)秋茫,如下圖:
14.png
3.1 依賴的jar包
依賴solrj及solrj依賴包.
15.png
以及l(fā)ib下的擴(kuò)展依賴包
16.png
3.1 使用solrj添加文檔
第一步:創(chuàng)建一個(gè)java工程
第二步:導(dǎo)入jar包火本。包括solrJ的jar包,依賴包簿盅,擴(kuò)展包(如上圖所示)

代碼開(kāi)發(fā)步驟:
第三步:和Solr服務(wù)器建立連接瞬内。HttpSolrServer對(duì)象建立連接。
第四步:創(chuàng)建一個(gè)SolrInputDocument對(duì)象秦躯,然后添加域昙沦。
第五步:將SolrInputDocument添加到索引庫(kù)徘钥。
第六步:提交。

//向索引庫(kù)中添加索引
@Test
public void addDocument() throws Exception {
    //和solr服務(wù)器創(chuàng)建連接
    //參數(shù):solr服務(wù)器的地址
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    //創(chuàng)建一個(gè)文檔對(duì)象
    SolrInputDocument document = new SolrInputDocument();
    //向文檔中添加域
    //第一個(gè)參數(shù):域的名稱亮隙,域的名稱必須是在schema.xml中定義的
    //第二個(gè)參數(shù):域的值
    document.addField("id", "c0001");
    document.addField("title_ik", "使用solrJ添加的文檔");  
    document.addField("product_name", "商品名稱");
    //把document對(duì)象添加到索引庫(kù)中
    solrServer.add(document);
    //提交修改
    solrServer.commit();    
}
3.2 刪除文檔
根據(jù)id刪除
//刪除文檔贱枣,根據(jù)id刪除
@Test
public void deleteDocumentByid() throws Exception {
    //創(chuàng)建連接
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    //根據(jù)id刪除文檔
    solrServer.deleteById("c0001");
    //提交修改
    solrServer.commit();
}

根據(jù)查詢刪除
//根據(jù)查詢條件刪除文檔
@Test
public void deleteDocumentByQuery() throws Exception {
    //創(chuàng)建連接
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    //根據(jù)查詢條件刪除文檔
    solrServer.deleteByQuery("*:*");
    //提交修改
    solrServer.commit();
}
3.3 修改文檔
在solrJ中修改沒(méi)有對(duì)應(yīng)的update方法吕世,只有add方法棠耕,只需要添加一條新的文檔输硝,和被修改的文檔id一致就可以修改了。
本質(zhì)上就是先刪除后添加。

@Test
public void testUpdate() throws IOException, SolrServerException {
    //連接SolrServer服務(wù)器
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    //獲取一個(gè)文檔對(duì)象,添加域
    SolrInputDocument document = new SolrInputDocument();
    document.addField("id","002");
    document.addField("name","testtest22222");
    //更新
    solrServer.add(document);
    //提交修改
    solrServer.commit();
}

4. 查詢文檔

4.1 簡(jiǎn)單查詢
//查詢索引
@Test
public void queryIndex() throws Exception {
    //創(chuàng)建連接
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    //創(chuàng)建一個(gè)query對(duì)象
    SolrQuery query = new SolrQuery();
    //設(shè)置查詢條件
    query.setQuery("*:*");
    //執(zhí)行查詢
    QueryResponse queryResponse = solrServer.query(query);
    //取查詢結(jié)果
    SolrDocumentList solrDocumentList = queryResponse.getResults();
    //共查詢到商品數(shù)量
    System.out.println("共查詢到商品數(shù)量:" + solrDocumentList.getNumFound());
    //遍歷查詢的結(jié)果
    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"));
    }
}
4.2 復(fù)雜查詢
@Test
//其中包含查詢、過(guò)濾、分頁(yè)、排序濒生、高亮顯示等處理厉碟。
public void testQuery2() throws SolrServerException {
    //獲取SolrServer連接
    SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
    //獲取查詢對(duì)象
    SolrQuery query = new SolrQuery();
    //設(shè)置查詢條件
    //query.set("q","id:1");
    //query.setQuery("1");
    query.setQuery("情侶");
    //設(shè)置過(guò)濾條件
    query.setFilterQueries("product_catalog_name:幽默雜貨");

    //排序(按價(jià)格從低到高排序)
    query.addSort("product_price", SolrQuery.ORDER.asc);
    //分頁(yè)處理
    query.setStart(0);
    query.setRows(20);

    //結(jié)果中顯示域的列表
    query.setFields("id", "product_name", "product_price", "product_catalog_name", "product_picture");

    //設(shè)置默認(rèn)搜索域
    query.set("df", "product_name");//這里以商品名稱作為默認(rèn)搜索域

    //高亮顯示,開(kāi)啟高亮開(kāi)關(guān)
    query.setHighlight(true);
    //高亮顯示的域
    query.addHighlightField("product_keywords");
    //高亮顯示的前綴
    query.setHighlightSimplePost("<em style='color:red'>");
    //高亮顯示的后綴
    query.setHighlightSimplePre("</em>");

    //執(zhí)行查詢
    QueryResponse queryResponse = solrServer.query(query);
    //獲取查詢的結(jié)果集
    SolrDocumentList solrDocumentList = queryResponse.getResults();

    //供查詢到商品數(shù)量
    System.out.println(solrDocumentList.getNumFound());

    //遍歷結(jié)果集
    for (SolrDocument document : solrDocumentList) {
        //高亮顯示的存儲(chǔ)位置不同,取出高亮顯示的商品名
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
        //以id存在大Map中,再根據(jù)高亮顯示的域從小Map中取出高亮顯示的List
        List<String> list = highlighting.get(document.get("id")).get(document.get("product_name"));

        //判斷是否有高亮內(nèi)容
        String product_name = null;
        if (list != null) {//有高亮顯示內(nèi)容
            product_name = list.get(0);
        } else {//沒(méi)有,就從document里面取
            product_name = (String) document.get("product_name");
        }

        System.out.println(product_name);
        System.out.println(document.get("id"));
        System.out.println(document.get("product_price"));
        System.out.println(document.get("product_catalog_name"));
        System.out.println(document.get("product_picture"));
    }
}

4. solr案例:模擬京東站內(nèi)搜索

4.1 使用上面已經(jīng)創(chuàng)建的索引庫(kù)
4.2 搭建java程序環(huán)境
第一步:創(chuàng)建一個(gè)web工程導(dǎo)入jar包
1、springmvc的相關(guān)jar包
2野舶、solrJ的核心包和依賴包
3劲蜻、Example\lib\ext下的jar包
4、拷貝靜態(tài)資源到工程項(xiàng)目webContent下

分析雏门,此案例暫時(shí)不用到持久化相關(guān)的比如mybatis相關(guān)的配置項(xiàng)年扩。而是使用solr索引庫(kù)
所以可以使用springmvc.xml作為spring容器進(jìn)行配置,因?yàn)閟pringmvc是spring的子容器格了。


第二步:配置文件與包結(jié)構(gòu)的創(chuàng)建

包結(jié)構(gòu):

17.png
web.xml:

    <!--解決Post請(qǐng)求亂碼-->
    <filter>
        <filter-name>encoding</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>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--springmvc前端控制器-->
    <servlet>
        <servlet-name>jd-springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:config/springmvc.xml</param-value>
        </init-param>
        <!--tomcat容器一啟動(dòng)就加載springmvc前端控制器-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jd-springmvc</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

--------------------------------------------------------------------------------

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="main.com.itdream.jd"/>
    
        <!--配置注解驅(qū)動(dòng),相當(dāng)于配置了處理器映射器,處理器適配器-->
        <mvc:annotation-driven/>
    
        <!--視圖解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>

    

第二步:Pojo:
    商品對(duì)象模型:
    public class ProductModel {
        // 商品編號(hào)
        private Integer pid;
        // 商品名稱
        private String name;
        // 商品分類名稱
        private String catalog_name;
        // 價(jià)格
        private Float price;    
        // 圖片名稱
        private String picture;
    }
    
    返回值對(duì)象模型
    public class ResultModel {
        // 商品列表
        private List<ProductModel> productList;
        // 商品總數(shù)
        private Long recordCount;
        // 總頁(yè)數(shù)
        private Integer pageCount;
        // 當(dāng)前頁(yè)
        private Integer curPage;
        // 每頁(yè)的行數(shù)
        private Integer rows;
    }

查詢條件對(duì)象QueryVo:
public class QueryVo implements Serializable {

    private String queryString;//關(guān)鍵字搜索
    private String catalog_name;//分類搜索
    private String price;//價(jià)格區(qū)間搜索
    private String sort;//排序

    private Integer page;//當(dāng)前頁(yè)
    private Integer rows;//每頁(yè)顯示條數(shù)
}
    

環(huán)境搭建完成看铆。
4.2 代碼開(kāi)發(fā)
從dao層開(kāi)始開(kāi)發(fā):
    功能:接收service層傳遞過(guò)來(lái)的參數(shù),根據(jù)參數(shù)查詢索引庫(kù)盛末,返回查詢結(jié)果弹惦。
    參數(shù):SolrQuery對(duì)象
    返回值:一個(gè)商品列表List<ProductModel>,還需要返回查詢結(jié)果的總數(shù)量悄但。
    返回:ResultModel
    方法定義:ResultModel search (SolrQuery query) throws Exception;

SearchDao:
/**
 * 根據(jù)查詢條件進(jìn)行搜索
 *
 * @param solrQuery
 * @return
 */
ResultModel search(SolrQuery solrQuery) throws Exception;

SearchDaoImpl :
@Repository
public class SearchDaoImpl implements SearchDao {

    @Autowired
    private SolrServer solrServer;

    @Override
    public ResultModel search(SolrQuery solrQuery) throws Exception {

        //1. 連接SolrServer索引庫(kù)服務(wù)器,交由Spring管理
        //2. 根據(jù)查詢條件執(zhí)行查詢
        QueryResponse queryResponse = solrServer.query(solrQuery);
        //根據(jù)查詢條件獲取結(jié)果集
        SolrDocumentList solrDocumentList = queryResponse.getResults();

        //獲取高亮內(nèi)容
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();

        //構(gòu)建ResultModel中的商品列表的ProductList集合
        List<ProductModel> productList = new ArrayList<>();
        ProductModel productModel = null;

        //遍歷結(jié)果集
        for(SolrDocument document : solrDocumentList) {
            productModel = new ProductModel();

            //獲取高亮
            List<String> list = highlighting.get(document.get("id")).get("product_name");

            String product_name = null;
            if(list != null && list.size() >0) { //有高亮
                product_name = list.get(0);
            }else {
                product_name = (String) document.get("product_name");
            }

            //獲取ProductModel的其他內(nèi)容
            //獲取id
            Integer id = null;
            Object idObj = document.get("id");
            if(idObj != null) {
                id = Integer.parseInt(idObj.toString());
            }

            //獲取分類名稱
            String product_catalog_name = (String)document.get("product_catalog_name");
            //獲取價(jià)格
            Float product_price = (Float) document.get("product_price");
            //獲取圖片名稱
            String product_picture = (String) document.get("product_picture");

            //設(shè)置到ProductModel中
            productModel.setPid(id);
            productModel.setName(product_name);
            productModel.setCatalog_name(product_catalog_name);
            productModel.setPrice(product_price);
            productModel.setPicture(product_picture);

            //將該P(yáng)roductModel添加到List中
            productList.add(productModel);
        }

        //3. 構(gòu)建ResultModel實(shí)例將查詢結(jié)果設(shè)置進(jìn)去
        ResultModel model = new ResultModel();

        //設(shè)置總頁(yè)數(shù)
        //設(shè)置當(dāng)前頁(yè)
        //設(shè)置每頁(yè)的行數(shù)
        //-------以上在service層設(shè)置----------

        //設(shè)置商品列表
        model.setProductList(productList);
        //設(shè)置商品總數(shù)
        model.setRecordCount(solrDocumentList.getNumFound());
        return model;
    }
}

---------------------------------------------------------------------------

ProductService :
public interface ProductService {

    /**
     * 根據(jù)查詢條件查詢ResultMoedl
     *
     * @param vo
     * @return
     */
    ResultModel getResultModelByQuery(QueryVo vo) throws Exception;
}


ProductServiceImpl 實(shí)現(xiàn)類:
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private SearchDao searchDao;

    @Override
    public ResultModel getResultModelByQuery(QueryVo vo) throws Exception {

        //構(gòu)建查詢條件,封裝查詢條件
        SolrQuery solrQuery = new SolrQuery();

        //判斷queryString是否為空
        if (!StringUtils.isEmpty(vo.getQueryString())) {
            //根據(jù)關(guān)鍵字搜索
            solrQuery.setQuery(vo.getQueryString());
        } else {
            solrQuery.setQuery("*:*");
            //solrQuery.set("q", "*:*");
        }

        //判斷分類搜索條件是否為空
        if (!StringUtils.isEmpty(vo.getCatalog_name())) {
            //分類搜索不為空
            solrQuery.setFilterQueries("product_catalog_name:" + vo.getCatalog_name());
        }

        //判斷價(jià)格搜索
        if (!StringUtils.isEmpty(vo.getPrice())) {
            //價(jià)格搜索不為空
            String[] split = vo.getPrice().split("-");
            solrQuery.setFilterQueries("product_price:[" + split[0] + " TO " + split[1] + "]");
        }

        //判斷排序
        String sort = vo.getSort();
        if (!StringUtils.isEmpty(sort)) {
            if ("0".equals(sort)) {//升序
                solrQuery.addSort("product_price", SolrQuery.ORDER.asc);
            } else {//降序
                solrQuery.addSort("product_price", SolrQuery.ORDER.desc);
            }
        }
        //指定默認(rèn)搜索域
        solrQuery.set("df", "product_keywords");

        //設(shè)置分頁(yè)條件查詢
        Integer page = vo.getPage();//當(dāng)前頁(yè)
        Integer rows = vo.getRows();//每頁(yè)顯示條數(shù)

        //設(shè)置第幾條開(kāi)始查詢
        Integer start = (page - 1) * rows;
        solrQuery.setStart(start);
        //設(shè)置差多少條
        solrQuery.setRows(rows);

        //開(kāi)啟高亮
        solrQuery.setHighlight(true);
        //指定高亮顯示的域
        solrQuery.addHighlightField("product_name");
        //設(shè)置高亮顯示文本的前綴
        solrQuery.setHighlightSimplePre("<em style=\"color:red\">");
        //設(shè)置高亮顯示文本的后綴
        solrQuery.setHighlightSimplePost("</em>");

        //-------查詢條件封裝完畢:包括默認(rèn)域查詢,過(guò)濾查詢,排序,分頁(yè)-------
        //調(diào)用dao查詢結(jié)果,獲取結(jié)果模型
        ResultModel resultModel = searchDao.search(solrQuery);

        //------在service層設(shè)置---------
        //設(shè)置當(dāng)前頁(yè)
        resultModel.setCurPage(page);
        //設(shè)置每頁(yè)的行數(shù)
        resultModel.setRows(rows);
        //設(shè)置總頁(yè)數(shù)
        Long recordCount = resultModel.getRecordCount();//總記錄數(shù)
        Long pageCount = (recordCount + rows - 1) / rows;
        resultModel.setPageCount(pageCount);

        return resultModel;
    }
}

@Controller
public class ProductController {

    @Autowired
    private ProductService productService;

    @RequestMapping("list.action")
    public String listByQuery(QueryVo vo, Model model) {
        try {

            //如果頁(yè)面未傳值,給一定的值給定默認(rèn)值
            if(vo.getPage() == null) {
                vo.setPage(1);
            }
            if(vo.getRows() == null) {
                vo.setRows(16);
            }
            if(vo.getSort() == null) {
                vo.setSort("1");
            }

            ResultModel resultModel = productService.getResultModelByQuery(vo);
            //添加數(shù)據(jù),根據(jù)頁(yè)面確定key
            model.addAttribute("result",resultModel);

            //回顯查詢條件,也是根據(jù)頁(yè)面確定key
            model.addAttribute("queryString",vo.getQueryString());
            model.addAttribute("catalog_name",vo.getCatalog_name());
            model.addAttribute("price",vo.getPrice());
            model.addAttribute("page",vo.getPage());
            model.addAttribute("sort",vo.getSort());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "product_list";
    }
}


-----
代碼開(kāi)發(fā)完成
4.3 注意的問(wèn)題
1. solr啟動(dòng)的tomcat可能會(huì)與程序運(yùn)行的tomcat沖突,在solr啟動(dòng)的tomcat中修改端口號(hào),我這里修改了8090.
要注意的是:這里修改之后,springmvc.xml中配置的solrServer連接服務(wù)器的配置記得更改:指定到具體的solrCore實(shí)例,否則會(huì)報(bào)錯(cuò):
    Expected mime type application/octet-stream but got text/html

springmvc.xml配置:
    <!--注冊(cè)SolrServer連接服務(wù)器-->
    <bean id="solrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
        <constructor-arg name="baseURL" value="http://localhost:8090/solr/collection1" />
    </bean>

2. 使用價(jià)格條件篩選的時(shí)候,格式是  product_pric:[10 TO *],閉括號(hào)代表包括,大括號(hào)代表不包括,星號(hào)代表無(wú)窮大或無(wú)窮小棠隐。
要注意的是:條件拼接要注意 TO 的兩邊要有空格

展示效果:

18.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市檐嚣,隨后出現(xiàn)的幾起案子助泽,更是在濱河造成了極大的恐慌,老刑警劉巖嚎京,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗡贺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鞍帝,警方通過(guò)查閱死者的電腦和手機(jī)诫睬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)膜眠,“玉大人岩臣,你說(shuō)我怎么就攤上這事∠颍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵炸宵,是天一觀的道長(zhǎng)辟躏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)土全,這世上最難降的妖魔是什么捎琐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮裹匙,結(jié)果婚禮上瑞凑,老公的妹妹穿的比我還像新娘。我一直安慰自己概页,他們只是感情好籽御,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般技掏。 火紅的嫁衣襯著肌膚如雪铃将。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天哑梳,我揣著相機(jī)與錄音劲阎,去河邊找鬼。 笑死鸠真,一個(gè)胖子當(dāng)著我的面吹牛悯仙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吠卷,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼雁比,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了撤嫩?” 一聲冷哼從身側(cè)響起偎捎,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎序攘,沒(méi)想到半個(gè)月后茴她,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡程奠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年丈牢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞄沙。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡己沛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出距境,到底是詐尸還是另有隱情申尼,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布垫桂,位于F島的核電站师幕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏诬滩。R本人自食惡果不足惜霹粥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疼鸟。 院中可真熱鬧后控,春花似錦、人聲如沸空镜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至馋袜,卻和暖如春男旗,著一層夾襖步出監(jiān)牢的瞬間栽惶,已是汗流浹背今缚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旅掂,地道東北人泽台。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓什荣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親怀酷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子稻爬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容