• Solr


    1.   总结

    1、SolrCore的配置

    a)schma.xml文件

    b)配置中文分析器

    2、配置业务域和批量索引导入

    a)配置业务域

    b)批量索引导入

    c)Solrj复杂查询(用Query页面复杂查询、用程序实现)

    3、京东案例(简单的站内搜索实现)

     

     


     

    2.SolrCore的配置(重点)

    SolrCore的运行由两个重要的配置文件做指导,一个是solrconfig.xml,一个是schema.xml

    1solrconfig.xml配置:

    SolrCore运行的核心要素(依赖包、数据目录)和基本功能:(索引CRUDweb请求处理器)等,这是SolrCore的核心配置文件。之前已经介绍过了。

    2schema.xml配置:

    ·域以及域类型的配置:

    SolrCore中的所有Field域都采用先配置才能使用的方式。域的配置必须在schema.xml中。

    SolrCore本身自带了一些域的定义以及这些域的类型定义,但就像MySQL数据库刚创建完就会有一个默认的mysql数据库一样,我们根本不会理睬里面有什么,也根本不用,都是我们自己根据实际业务需求重新定义自己的数据库。SolrCore中的Field也是一样,它自带的基本什么用都没有,这个我们昨天也看到了。我们真正使用的都是根据我们业务需求重新创建Field域。

    2.1. schema.xml

    schema.xml文件在SolrCoreconf目录下,此配置文件中不仅定义了域还定义了域的类型。在solr中的域必须先定义后使用。

     

    2.1.1. field

       <field name="id" type="string"indexed="true" stored="true"required="true" multiValued="false"/>

     

    l  name必须):域的名称

    l  indexed必须):是否索引,在Lucene学习中我们知道是否索引是由域的类型决定的,但是solr在此做了域的增强,可以直接在域的配置中自行决定是否索引了。

    l  stored必须):是否存储

    (注意:似乎缺少一个【是否分词】的配置属性,通过Lucene学习我们知道是否分词是由域的类型决定的,Solr在此处仍然保持了这个特性,由域的类型决定是否分词。

    l  type必须):域类型的别名,Solr可以给域类型配置所需的分析器,然后给这个配置起个别名,然后这个别名就可以用来定义域的配置。这样设计的好处是同一种域类型根据需求可以配置出多种不同的分词能力,可以获得更好的扩展性。

    l  required(可选):是否为必须项,true表示文档中必须存在该域,反之为false,不配置时默认为falseschema.xml中只配置了id域为必须项)

    l  multiValued(可选):是否允许域中保存多个值,true表示允许,反之为false,不配置时默认为false

    多值的情况:比如存储一个商品的多个图片地址(大图、小图、缩略图)。

     

    2.1.2. fieldType(域类型配置)

    Solr可以针对它的域类型做不同的配置:这里面最重要的是配置分析器。

    <fieldType name="text_general"class="solr.TextField" positionIncrementGap="100">

    <analyzer type="index">

            <tokenizer class="solr.StandardTokenizerFactory"/>

            <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>

            <!-- in this example, we will only use synonyms at query time

            <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>

            -->

            <filter class="solr.LowerCaseFilterFactory"/>

    </analyzer>

    <analyzer type="query">

            <tokenizer class="solr.StandardTokenizerFactory"/>

            <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>

            <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>

            <filter class="solr.LowerCaseFilterFactory"/>

    </analyzer>

        </fieldType>

     

    l  name:域类型的别名

    l  class:指定solr的域类型。

    l  analyzer:指定分词器,包括分词器和各种过滤器

    还可以直接指定一个分析器的class类,这样就使用这个分析器中默认的分词器和过滤器,而不需要再配置分词器和过滤器了。这样的配置更加简化。

    l  type:两个值:indexqueryindex 是创建索引,query是查询索引。

    l  tokenizer:指定分词器

    l  filter:指定过滤器

     

    2.1.3. dynamicField(动态域)

       <dynamicField name="*_s"  type="string"    indexed="true"  stored="true"/>

    name:动态域的名称,是一个表达式,*匹配任意字符,只要域的名称和表达式的规则能够匹配就可以使用。

    其他属性和正常field域配置一样,没有区别。

    例如:添加索引id=zjl001zhoujielun_s=zhoujielun001,其中zhoujielun_sschema.xml中没有配置,但是这个符合动态域【*_s】,所以仍然可以添加:

        @Test

        public void testCreateIndex() throws Exception {

             // URL

             String baseUrl = "http://localhost:8081/solr/collection1";

             // 创建HttpSolrServer

             HttpSolrServer solrServer = new HttpSolrServer(baseUrl);

             // 创建document对象

             SolrInputDocument document = new SolrInputDocument();

             document.addField("id", "zjl001");

             document.addField("zhoujielun_s", "zhoujielun001");

             solrServer.add(document);

             solrServer.commit();

        }

     

    2.1.4. uniqueKey

     <uniqueKey>id</uniqueKey>

    强制声明该域在文档对象中必须是唯一的,相当于主键。

    2.1.5. copyField(复制域)

       <copyField source="cat"dest="text"/>

    Solr支持将多个域的内容拷贝到一个新的域中,好处是对拷贝后的新域的内容进行查询就是对多个域的内容进行统一的检索。

    l  source:源域

    l  dest:目标域,将源域拷贝到目标域时,solr会对拷贝到一起的内容做优化处理,这样搜索时,指定目标域为默认搜索域,可以提高查询效率。

    l  无论是源还是目标都得是已经存在的域,并且目标域的multiValued推荐为true

    定义目标域:

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

     

    2.2. 配置中文分析器

    中文分析器需要在Solr服务中配置,使用IKAnalyzer中文分析器。

    第一步:将IK分析器的jar包配置到Solr服务中。

    IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目录下。

         

     

    第二步:将IK需要的配置文件和词库加到Solr服务中

    solr/WEB-INF/下创建classes文件夹,用于存放IK分析器词库配置文件、自定义扩展词库、停用词词库。然后把这些文件复制solr/WEB-INF/classes目录下。

         

    第三步:将日志配置文件添加到Solr服务中

    如果想在cmd中输出日志需要在classes下添加log4j.properties

       

       

     

    第四步:在schema.xml中配置IK分析器

    schema.xml中添加一个自定义的fieldType,使用中文分析器。

    <!-- fileType with IKAnalyzer -->

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

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

        </fieldType>

     

    第五步:在schema.xml中配置支持IK的域

    schema.xml中添加field,指定fieldtype属性为text_ik

    <!-- IKAnalyzer Field -->

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

     

    第六步:重启tomcat

    效果:

     

    3.以业务需求进行域的配置和批量索引(重点)

    3.1. 业务需求

    如果有一个创建站内搜索的需求,就需要将数据库中的数据导入到SolrCore中创建索引库,然后利用solr服务实现网站中站内商品搜索。

    1. 需要确定数据库中检索出来的字段和数据

    2. 根据数据库中查询出的字段在SolrCoreschema.xml中配置业务需要的Field域。

    3. 需要实现一个能够批量导入数据到SolrCore索引库的功能。

    4. 测试导入的索引

    3.2. 数据库的字段和数据

    3.2.1. 导入数据SQL脚本

    在数据库中运行solr.sql脚本

     

    导入数据:总共3803条数据

     

    3.2.2. 查询SQL

    SELECT pid,name,catalog_name,price,description,picture,release_time FROM products

    3.3. 定义业务Field

    先确定定义的商品documentField域有哪些?

    可以根据我们要查询的有哪些商品表的字段来确定:

    products商品表:

    SolrCoreschema.xml中配置业务域,就根据我们检索的字段来创建:

    <!-- products Field -->

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

    <field name="product_catalog_name"type="string" 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_release_time"type="date" indexed="true"stored="true" />

    <!-- products copyField -->

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

    注意:这里没有创建idfield,因为在schema.xml中默认自带idfield,而且必须包含这个id域,所以这里不用建。

    3.4. 批量导入索引

    在昨天也介绍solr的可视化管理工具中有一个Dataimport功能,就是用于批量导入数据创建索引的:

    在上一节我们已经事先配置了业务域,下面需要利用批量导入插件将mysql中的products表中的数据批量创建索引:

    3.4.1. 第一步:导入插件依赖jar

    先在一个SolrCore实例(collection1)下创建一个lib文件夹,然后把dataimport插件依赖的jar包添加到lib, 同时还需要mysql的数据库驱动。

     

    3.4.2. 第二步:配置solrconfig.xml

    配置solrconfig.xml文件,添加一个requestHandler

    <!-- A request handler that dataimport -->

    <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,与solrconfig.xml保存到同目录下

    <?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="123"/>  

        <document>  

             <entity name="product"transformer="DateFormatTransformer"

    query="SELECT pid,name,catalog_name,price,description,picture,release_time 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"/>

                  <field column="release_time"name="product_release_time" dateTimeFormat="yyyy-MM-dd HH:mm:ss"/>

             </entity>  

        </document>  

    </dataConfig>

     

    上面的配置也可以从帮助文档中获得:

       

       

    会跳转到solrwiki:需要连网访问

     

    从中找到一个合适的配置即可:

     

    关于时间的配置:

    搜索【DateFormat】即可搜索到关于日期时间的相关配置:

    DateFormatTransformer】属于【Transformer】的一个值:

     

     

     

     

     

     

     

     

     

     

     

     

    3.4.3. 第三步:重启tomcat

    重启tomcat,然后刷新页面,点击Dataimport就可以看到这个导入界面了:

    点击“execute”按钮导入数据。

    界面重要选项说明:

        ·Command

    full-import表示全部导入

    delta-import表示差分导入(把缺少的部分导入进来)

    一般我们为了导入的数据完整,都采用full-import

    ·Clean:(默认选中)表示导入数据前会自动清空之前的索引文件

    ·Commit:(默认选中)表示创建的索引会自动提交

    ·Auto-Refresh Status:(默认不选中)它是控制到导入数据过程中界面是否自动刷新,默认不自动,要想自动选中即可。

    导入成功界面:

    3.5. 测试导入的索引

    3.5.1. solr的查询语法

    1.   q:查询关键字,必须的。

    请求的q是字符串,如果查询所有使用*:*

     

    2.   fq: (filter query)过滤查询

    作用:在q查询符合结果中同时是fq查询符合的

    请求fq是一个数组(多个值)

     

    过滤查询价格从120的记录。

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

    20以上:product_price:[20 TO *]

    20以下:product_price:[* TO 20]

     

    也可以在“q”查询条件中使用product_price:[1 TO 20]

    如下效果和上面一样:

     

    3.   sort:  排序,desc代表降序,asc代表升序

    按照价格升序排

     

     

    4.   start: 分页显示使用,开始记录下标,从0开始

    rows:  指定返回结果最多有多少条记录,配合start来实现分页。

     

    5.   fl: (Field List)指定返回那些字段内容,用逗号或空格分隔多个。

    显示商品id、商品名称、商品分类名称

     

    6.   df: 指定默认搜索Field

     

    7.   wt: (writer type)指定输出格式,可以有 xml, json, php, python

     

    8.   hl: 是否高亮 ,设置高亮Field,设置格式前缀和后缀。

    3.5.2. solrj的复杂查询

    页面的查询条件,复杂查询条件和页面的查询条件一致

       

    上面的查询条件也可以用代码实现:

        /**

         * solrj复杂查询

         *

         * @throws Exception

         */

        @Test

        public void complexSearchIndexTest() throws Exception {

             // 查询条件设置

             SolrQuery solrQuery = setQueryConditions();

             // 执行查询

             QueryResponse response = solrServer.query(solrQuery);

             // 处理查询查询结果

             dealSearchResult(response);

        }

       

        // 查询条件设置

        private SolrQuery setQueryConditions() throws Exception {

             SolrQuery query = new SolrQuery();

             // 设置查询条件

             query.setQuery("台灯");

            

             // 设置过滤条件

             query.setFilterQueries("product_catalog_name:雅致灯饰", "product_price:[30 TO 40]");

             // 或者分开设置

             /*query.setFilterQueries("product_catalog_name:雅致灯饰");

             query.setFilterQueries("product_price:[30 TO 40]");*/

            

             // 设置排序条件

             query.setSort("product_price", ORDER.desc);

            

             // 设置分页信息(开始行号和每页数据量)

             query.setStart(0);

             query.setRows(10);

            

             // 设置需要显示的域名(可选,不设置时全部显示)

             //query.setFields("id", "product_name", "product_price");

            

             // 设置默认搜索域

             query.set("df", "product_name");

            

             // 设置高亮显示(是否开启高亮显示,高亮显示的域名,高亮的前缀和后缀)

             query.setHighlight(true);

             query.addHighlightField("product_name");

             query.setHighlightSimplePre("<font color="red">");

             query.setHighlightSimplePost("</font>");

            

             return query;

        }

       

        // 处理查询结果

        private void dealSearchResult(QueryResponse response) throws Exception {

             // 取得商品信息结果集

             SolrDocumentList results = response.getResults();

            

             // 取得高亮信息结果集

             Map<String, Map<String, List<String>>> hlResults = response.getHighlighting();

            

             // 打印结果件数

             System.out.println("查询结果总件数:" + results.getNumFound());

            

             // 遍历结果集打印结果

             for (SolrDocument doc : results) {

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

                 // 处理高亮显示的内容

                 String hlValue = dealHighlighting(hlResults, doc, "product_name");

                

                 // 输出结果

                 System.out.println("id:" + doc.get("id"));

                 System.out.println("product_name:" + hlValue);

                 System.out.println("product_price:" + doc.get("product_price"));

                 System.out.println("product_catalog_name:" + doc.get("product_catalog_name"));

                 System.out.println("product_picture:" + doc.get("product_picture"));

             }

        }

       

        // 处理高亮显示内容

        private String dealHighlighting(Map<String, Map<String, List<String>>> hlResults,

                 SolrDocument doc, String hlField) throws Exception {

             // 先取得原版的域值

             String orgFieldValue = (String)doc.get(hlField);

            

             // 判断高亮结果集中是否包含当前文档的高亮信息

             if (hlResults != null) {

                 List<String> list = hlResults.get(doc.get("id")).get(hlField);

                 if (list != null && list.size() > 0) {

                      return list.get(0);

                 }

             }

             return orgFieldValue;

        }

     

    4.案例(重点)

    4.1. 需求

    使用Solr实现电商网站中商品信息搜索功能,可以根据关键字搜索商品信息,根据商品分类、价格过滤搜索结果,也可以根据价格进行排序,实现分页。

    界面如下:

     

     

    4.1.1. 架构分析

    架构分为:

    1、 solr服务器

    2、 自己的web服务器(需要开发)

    3、 数据库mysql

     

    自己开发的应用

    1、 Controller

    获取搜索条件,调用查询站内搜索service进行查询,并响应搜索结果到前台页面。

    2、 Service

    Service调用dao, 用前台传入的查询条件创建SolrQuery对象,然后传给DAO,进行搜索。

    Service调用dao进行商品数据的维护时,要同步更新索引库(本案例不实现)

    3、 Dao

    根据service传入的SolrQuery对象,对solr的索引库进行搜索,并返回查询结果。

    对商品数据进行维护和查询(本案例不实现)

    4.2. 环境准备

    l  Solr4.10.3

    l  Jdk环境:1.7

    l  IDE环境:eclipse Mars2

    l  服务器:Tomcat 7

    4.3. 工程搭建(UTF-8

    创建一个web工程导入jar

    1、spring的相关jar

    2、solrJjar包和依赖jar

    3、Solr服务的日志依赖包,solrexamplelibext下的jar

    创建后完整的工程:

    1. 导入jar包后,先创建目录:daopojoservicecontrollerconfigjsp

    2. 导入配置文件:

    1) 表现层SpringMVC.xml@controller注解扫描,注解驱动,视图解析器

    2) 业务层ApplicationContext.xml@Service@Repository注解扫描、solrj连接Solr服务的bean

    (注意:这里面没有集成mybatis,所以我们用注解@Repository来注入,这样DAO需要有实现类我们自己编写。)

    3) web.xmlSpringMVC的前端控制器和Spring监听

    4) log4j.properties

    3. 导入jsp页面:【资料jd案例product_list.jsp

    4. 导入静态资源:【资料jd案例】下的【images】【resource】拷贝到工程【WebContent】下。

    5. 导入pojo:【资料jd案例pojo】下的【ProductModel.java】【ResultModel.java

    6. ApplicationContext.xml中配置SolrServer:

        <!-- 配置solr server bean -->

        <bean id="solrServer"class="org.apache.solr.client.solrj.impl.HttpSolrServer">

             <!-- 配置Solr Server实例时需要的构造函数的参数 -->

             <constructor-arg value="http://127.0.0.1:8081/solr/collection1"/>

        </bean>

     

    4.4. Dao

    功能:接收service层传递过来的参数,根据参数查询索引库,返回查询结果。

    参数:SolrQuery对象

    返回值:一个商品列表List<ProductModel>,还需要返回查询结果的总数量。

    返回:ResultModel

    方法定义:ResultModel searchProductList(SolrQuery query) throws Exception;

     

     

    商品对象模型:

    public class ProductModel {

        // 商品编号

        private String pid;

        // 商品名称

        private String name;

        // 商品分类名称

        private String catalog_name;

        // 价格

        private float price;

        // 商品描述

        private String description;

        // 图片名称

        private String picture;

        // setter/getter......

    }

     

    返回值对象模型

    public class ResultModel {

        // 商品列表

        private List<ProductModel> productList;

        // 商品总数

        private Long recordCount;

        // 总页数

        private int pageCount;

        // 当前页

        private int curPage;

        // setter/getter......

    }

     

    package cn.itcast.dao;

    import java.util.ArrayList;

    import java.util.List;

    import java.util.Map;

    import org.apache.solr.client.solrj.SolrQuery;

    import org.apache.solr.client.solrj.SolrServer;

    import org.apache.solr.client.solrj.response.QueryResponse;

    import org.apache.solr.common.SolrDocument;

    import org.apache.solr.common.SolrDocumentList;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Repository;

    import cn.itcast.pojo.ProductModel;

    import cn.itcast.pojo.ResultModel;

     

    @Repository

    public class ProductDaoImpl implements ProductDao {

        @Autowired

        private SolrServer solrServer;

        @Override

        public ResultModel searchProductList(SolrQuery query) throws Exception {

             // 执行查询,并返回结果

             QueryResponse queryResponse = solrServer.query(query);

             // 从结果对象中取得结果集

             SolrDocumentList results = queryResponse.getResults();

             // 取得高亮信息结果集

             Map<String, Map<String, List<String>>> hlResults = queryResponse.getHighlighting();

             // 创建返回结果对象

             ResultModel resultModel = new ResultModel();

             // 创建结果集list

             List<ProductModel> productList = new ArrayList<ProductModel>();

             // 查询件数

             resultModel.setRecordCount(results.getNumFound());

             // 遍历结果集打印详细内容

             for (SolrDocument doc : results) {

                 // 创建一个ProductModel查询结果

                 ProductModel productModel = new ProductModel();

                

                 // 取得高亮显示的信息,然后根据高亮显示的信息进行结果信息打印

                 String productName = (String)doc.get("product_name");

                 if (hlResults != null) {

                      List<String> list = highlighting.get(doc.get("id")).get("product_name");

                      if (list != null && list.size() > 0) {

                          productName = list.get(0);

                      }

                 }

                 // 商品id

                 productModel.setPid(String.valueOf(doc.get("id")));

                 // 商品名称

                 productModel.setName(productName);

                 // 商品价格

                 String price = String.valueOf(doc.get("product_price"));

                 if (price != null && !"".equals(price)) {

                      productModel.setPrice(Float.parseFloat(price));

                 }

                 // 商品图片

                 productModel.setPicture(String.valueOf(doc.get("product_picture")));

                 // 添加到商品列表中

                 productList.add(productModel);

             }

             if (productList.size() > 0) {

                 resultModel.setProductList(productList);

             }

             return resultModel;

        }

    }

     

    4.5. Service

    功能:接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。接收返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。

    参数:

    1、查询条件:字符串

    2、商品分类的过滤条件:商品的分类名称,字符串

    3、商品价格区间:传递一个字符串,满足格式:“0-100101-200201-*”

    4、排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序

    5、分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。

    返回值:ResultModel

     

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

    package cn.itcast.service;

    import org.apache.solr.client.solrj.SolrQuery;

    import org.apache.solr.client.solrj.SolrQuery.ORDER;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Service;

    import cn.itcast.dao.ProductDao;

    import cn.itcast.pojo.ResultModel;

    @Service

    public class ProductServiceImpl implements ProductService {

        // 每页显示60条数据

        private static final Integer PAGE_SIZE = 60;

        @Autowired

        private ProductDao prodDao;

        @Override

        public ResultModel search(String queryString, String catalog_name,

                 String price, Integer page, String sort)

                 throws Exception {

             // 封装查询条件

             SolrQuery solrQuery = new SolrQuery();

             // 设置默认查询域

             solrQuery.set("df", "product_keywords");

             // 设置查询条件

             if (queryString != null && !"".equals(queryString)) {

                 solrQuery.setQuery(queryString);

             } else {

                 solrQuery.setQuery("*:*");

             }

             // 根据分类过滤

             if (catalog_name != null && !"".equals(catalog_name)) {

                 solrQuery.addFilterQuery("product_catalog_name:" + catalog_name);

             }

    //       else {

    //           // 注意这里要说一下为什么没有else,因为过滤条件不是必须的所以可以没有.

    //       }

             // 价格过滤

             if (price != null && !"".equals(price)) {

                 String[] split = price.split("-");

                 if (split != null && split.length > 0) {

                      solrQuery.addFilterQuery("product_price:[" + split[0] + " TO " + split[1] + "]");

                 }

             }

             // 排序

             if ("1".equals(sort)) {

                 solrQuery.setSort("product_price", ORDER.asc);

             } else {

                 solrQuery.setSort("product_price", ORDER.desc);

             }

             // 分页

             if (page == null || page <= 0) {

                 page = 1;

             }

             // 从第几条开始

             solrQuery.setStart((page - 1) * PAGE_SIZE);

             // 每页显示多少条

             solrQuery.setRows(PAGE_SIZE);

             // 设置高亮

             solrQuery.setHighlight(true);

             // 设置高亮显示的域

             solrQuery.addHighlightField("product_name");

             // 设置高亮前缀

             solrQuery.setHighlightSimplePre("<span style="color:red">");

             // 设置高亮后缀

             solrQuery.setHighlightSimplePost("</span>");

             // 根据查询条件取得结果

             ResultModel resultModel = prodDao.search(solrQuery);

             // 设置当前页

             resultModel.setCurPage(page);

             // 计算总页数

             Long pageCount = resultModel.getRecordCount() / PAGE_SIZE;

             if (resultModel.getRecordCount() % PAGE_SIZE > 0) {

                 pageCount++;

             }

             resultModel.setPageCount(pageCount);

             return resultModel;

        }

    }

     

    4.1. Controller

    功能:接收页面传递过来的参数调用service查询商品列表。将查询结果返回给jsp页面,还需要查询参数的回显。

     

    参数:

    1、查询条件:字符串

    2、商品分类的过滤条件:商品的分类名称,字符串

    3、商品价格区间:传递一个字符串,满足格式:“0-100101-200201-*”

    4、排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序

    5、分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。

    6Model:相当于request

     

    返回结果:String类型,就是一个jsp的名称。

     

    String queryProduct(String queryString, String caltalog_name, String price, String sort, Integer page, Model model) throws Exception;

    package cn.itcast.controller;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    import cn.itcast.pojo.ResultModel;

    import cn.itcast.service.ProductService;

    @Controller

    public class ProductController {

        @Autowired

        private ProductService prodService;

        @RequestMapping("/list")

        public String list(String queryString, String catalog_name,

                 String price, Integer page, String sort, Model model) throws Exception {

             ResultModel resultModel = prodService.search(queryString, catalog_name, price, page, sort);

         // 搜索结果返回

             model.addAttribute("result", resultModel);

             // 回显查询条件

             model.addAttribute("queryString", queryString);

             model.addAttribute("catalog_name", catalog_name);

             model.addAttribute("price", price);

             model.addAttribute("sort", sort);

             return "product_list";

        }

    }

     






    出身决定命运,但努力一定不会错。
  • 相关阅读:
    深入了解CSS3新特性(转)
    微小,但是美好的改变 G2 2.2发布
    可视化框架设计-数据调整
    可视化框架设计-图表类型
    可视化框架设计-数据流
    人之初,性本动
    可视化框架设计-坐标系
    可视化框架设计-视觉通道
    可视化框架设计-数据类型
    可视化框架设计-整体思路
  • 原文地址:https://www.cnblogs.com/xiaolige/p/8481643.html
Copyright © 2020-2023  润新知