Web-第二十九天 Lucene&solr使用二【悟空教程】

2018-08-06 17:36:37 浏览数 (1)

Web-第二十九天 Lucene&solr使用二【悟空教程】

12. Solrj的使用(重点)

13. solr基本使用

a) schma.xml文件

b) 配置中文分词器

c) 配置业务域

d) DataimportHandler插件

14. Solrj的复杂查询

a) solr的查询语法

b) solrj的复杂查询

15. 京东商城学习案例

12. Solrj的使用

12.1. 什么是solrj

solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,如下图:

Solrj和图形界面操作的区别就类似于数据库中使用jdbc和mysql客户端的区别一样。

12.2. 需求

使用solrj调用solr服务实现对索引库的增删改查操作。

12.3. 环境准备

  • Solr:4.10.3
  • Jdk环境:1.7
  • IDE环境:Eclipse Mars2

12.4. 工程搭建

12.4.1. 创建java工程

12.4.2. 添加jar

Solrj的包,solr-4.10.3dist目录下

solrj依赖包,solr-4.10.3distsolrj-lib

Solr服务的依赖包,solrexamplelibext

12.5. 代码实现

12.5.1. 添加&修改索引

12.5.1.1. 步骤

1.创建HttpSolrServer对象,通过它和Solr服务器建立连接。

2.创建SolrInputDocument对象,然后通过它来添加域。

3.通过HttpSolrServer对象将SolrInputDocument添加到索引库。

4.提交。

12.5.1.2. 代码

说明:根据id(唯一约束)域来更新Document的内容,如果根据id值搜索不到id域则会执行添加操作,如果找到则更新。

@Test

public void testCreateAndUpdateIndex() throws Exception {

// 1. 创建HttpSolrServer对象

// 设置solr服务接口,浏览器客户端地址http://127.0.0.1:8081/solr/#/

String baseURL = "http://127.0.0.1:8081/solr/";

HttpSolrServer httpSolrServer = new HttpSolrServer(baseURL);

// 2. 创建SolrInputDocument对象

SolrInputDocument document = new SolrInputDocument();

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

document.addField("content ", "Hello world!");

// 3. 把SolrInputDocument对象添加到索引库中

httpSolrServer.add(document);

// 4. 提交

httpSolrServer.commit();

}

12.5.2. 删除索引

12.5.2.1. 代码

抽取HttpSolrServer 的创建代码

private HttpSolrServer httpSolrServer;

// 提取HttpSolrServer创建

@Before

public void init() {

// 1. 创建HttpSolrServer对象

// 设置solr服务接口,浏览器客户端地址http://127.0.0.1:8081/solr/#/

String baseURL = "http://127.0.0.1:8081/solr/";

this.httpSolrServer = new HttpSolrServer(baseURL);

}

删除索引逻辑,两种:

根据id删除

根据条件删除,根据条件删除

可以使用*:*作为条件,就是删除所有数据(慎用)

@Test

public void testDeleteIndex() throws Exception {

// 根据id删除索引数据

// this.httpSolrServer.deleteById("c1001");

// 根据条件删除(如果是*:*就表示全部删除,慎用)

this.httpSolrServer.deleteByQuery("*:*");

// 提交

this.httpSolrServer.commit();

}

神奇马戏团之动物饼干

主演:艾米莉·布朗特 / 约翰·卡拉辛斯基 / 伊恩·麦克莱恩

猫眼电影演出 广告

购买

12.5.3. 查询索引

12.5.3.1. 简单查询

/**

* 简单搜索

*

* @throws Exception

*/

@Test

public void testSearchIndex1() throws Exception {

// 创建搜索对象

SolrQuery query = new SolrQuery();

// 设置搜索条件

query.setQuery("*:*");

// 发起搜索请求

QueryResponse response = this.httpSolrServer.query(query);

// 处理搜索结果

SolrDocumentList results = response.getResults();

System.out.println("搜索到的结果总数:" results.getNumFound());

// 遍历搜索结果

for (SolrDocument solrDocument : results) {

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

System.out.println("id:" solrDocument.get("id"));

System.out.println("content" solrDocument.get("content"));

}

}

13. solr基本使用

13.1. schema.xml

schema.xml文件在SolrCore的conf目录下,在此配置文件中定义了域以及域的类型等一些配置。在solr中域必须先定义后使用。

13.1.1. field

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

  • Name:域的名称
  • Type:域的类型
  • Indexed:是否索引
  • Stored:是否存储
  • Required:是否必须
  • multiValued:是否是多值,存储多个值时设置为true,solr允许一个Field存储多个值,比如存储一个用户的好友id(多个),商品的图片(多个,大图和小图)

13.1.2. dynamicField(动态域)

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

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

例如:搜索时查询条件[product_i:钻石]就可以匹配这个动态域,可以直接使用,不用单独再定义一个product_i域。

13.1.3. uniqueKey

<uniqueKey>id</uniqueKey>

相当于主键,每个文档中必须有一个id域。

13.1.4. copyField(复制域)

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

可以将多个Field复制到一个Field中,以便进行统一的检索。当创建索引时,solr服务器会自动的将源域的内容复制到目标域中。

  • source:源域
  • dest:目标域,搜索时,指定目标域为默认搜索域,可以提高查询效率。

定义目标域:

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

目标域必须要使用:multiValued="true"

13.1.5. fieldType(域类型)

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

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

  • name:域类型的名称
  • class:指定域类型的solr类型。
  • analyzer:指定分词器。在FieldType定义的时候最重要的就是定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词和过滤。
  • type:index和query。Index 是创建索引,query是查询索引。
  • tokenizer:指定分词器
  • filter:指定过滤器

13.2. 配置中文分析器

使用IKAnalyzer中文分析器

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

第二步:复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的solr/WEB-INF/classes目录下。

复制IK分词器配置文件、自定义词典、停用词词典

粘贴到Tomcat的solr的/WEB-INF/classes目录下

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

<!-- IKAnalyzer-->

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

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

</fieldType>

第四步:在schema.xml中添加field,指定field的type属性为text_ik

<!--IKAnalyzer Field-->

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

第五步:重启tomcat

效果:

13.3. 配置业务Field

13.3.1. 需求

要使用solr实现网站中商品搜索,需要将mysql数据库中数据在solr中创建索引。

1. 需要在solr的schema.xml文件定义要存储的商品Field。

2. 需要把MySQL的数据导入到solr索引库中

3. 开发搜索功能

13.3.2. 数据库添加数据

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

13.3.3. 定义Field

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

可以根据mysql数据库中商品表的字段来确定:

products商品表:

商品document的field包括:pid、name、catalog、catalog_name、price、description、picture

pid:商品id主键

使用solr本身提供的:

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

name:商品名称

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

catalog:商品分类id

<field name="product_catalog" type="int" indexed="false" stored="true"/>

catalog_name:商品分类名称

<field name="product_catalog_name" type="string" indexed="true" stored="true" />

price:商品价格

<field name="product_price" type="double" indexed="true" stored="true" />

description:商品描述

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

picture:商品图片

<field name="product_picture" type="string" indexed="false" stored="true"/>

配置复制域

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

<copyField source="product_name" dest="product_keywords"/>

<copyField source="product_catalog_name" dest="product_keywords"/>

<copyField source="product_description" dest="product_keywords"/>

效果:

13.4. dataimportHandler插件

13.4.1. 添加jar包

13.4.1.1. 添加DataImportjar包

复制dist目录中的solr-dataimporthandler-4.10.3.jar

粘贴到contribdataimporthandlerlib

没有lib目录,需要手动创建(可以不放lib文件夹中,后面的配置文件路径匹配即可)

13.4.1.2. 添加数据库驱动包

复制MySQL驱动包

粘贴到contribdblib

contrib没有dblib目录,需要手动创建

13.4.1.3. 修改配置文件,加载jar包

修改solrconfig.xml,加载刚刚复制进来的jar包

添加以下配置即可:

<lib dir="${solr.install.dir:../..}/contrib/dataimporthandler/lib" regex=".*.jar" />

<lib dir="${solr.install.dir:../..}/contrib/db/lib" regex=".*.jar" />

效果:

13.4.2. 配置requestHandler

在solrconfig.xml配置文件中添加:

<requestHandler name="/dataimport"

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

<lst name="defaults">

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

</lst>

</requestHandler>

效果如下图

13.4.3. 创建data-config.xml配置文件

在collection1conf目录下创建data-config.xml文件

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

<dataConfig>

<dataSource type="JdbcDataSource"

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://127.0.0.1:3306/solr"

user="root"

password="root"/>

<document>

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

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

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

<field column="catalog" name="product_catalog"/>

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

13.4.4. 重启tomcat

重启Tomcat,刷新页面,进入DataImport功能页

13.4.5. 点击“execute”按钮导入数据

注意:导入数据前会先清空索引库,然后再导入。

导入成功:

14. solrj的复杂查询

14.1. solr的查询语法

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

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

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

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

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

过滤查询价格从1到20的记录。

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

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, phps

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

14.2. solrj的复杂查询

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

代码实现:

/**

* 复杂查询

* @throws Exception

*/

@Test

public void testSearchIndex2() throws Exception {

// 创建搜索对象

SolrQuery solrQuery = new SolrQuery();

// 设置查询条件

solrQuery.setQuery("蜡笔小新");

// 设置过滤条件

solrQuery.setFilterQueries("product_catalog_name:时尚卫浴","product_price:[5.5 TO 20]");

// 设置排序

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

// 设置分页

solrQuery.setStart(0);

solrQuery.setRows(10);

// 设置显示Field域

solrQuery.setFields("id,product_name,product_catalog_name,product_price,product_picture");

// 设置默认搜索Field域

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

// 设置高亮

solrQuery.setHighlight(true);

solrQuery.addHighlightField("product_name");

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

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

// 查询数据

QueryResponse response = this.httpSolrServer.query(solrQuery);

SolrDocumentList results = response.getResults();

System.out.println("搜索到的数据总条数:" results.getNumFound());

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

// 解析查询结果

for (SolrDocument solrDocument : results) {

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

// 获取高亮数据

List<String> list = map.get(solrDocument.get("id")).get("product_name");

System.out.println("商品ID:" solrDocument.get("id"));

// 显示高亮

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

System.out.println("商品名称:" list.get(0));

} else {

System.out.println("商品名称:" solrDocument.get("product_name"));

}

System.out.println("商品分类名称:" solrDocument.get("product_catalog_name"));

System.out.println("商品价格:" solrDocument.get("product_price"));

System.out.println("商品图片地址:" solrDocument.get("product_picture"));

}

}

15. 案例

15.1. 需求

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

界面如下:

15.2. 分析

开发人员需要的文档:原型设计、静态页面(前端团队提供)、数据库设计。

15.2.1. UI分析

15.2.2. 架构分析

架构分为:

1.solr服务器

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

3.数据库mysql

自己开发的应用

1.Controller

获取搜索条件,并响应搜索结果到前台页面。

2.Service

使用solrj来调用solr的服务进行索引和搜索

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

3.Dao(本案例不实现)

对商品数据进行维护和查询

15.3. 环境准备

  • Solr:4.10.3
  • Jdk环境:1.7
  • IDE环境:eclipse Mars2
  • 服务器:Tomcat 7

15.4. 工程搭建

15.4.1. 创建动态web工程

15.4.2. 加入jar包

需要的jar包

1. Spring的包(包括SpringMVC)

a) 拷贝springmvc-first的jar包

2. Solr的包(核心包,依赖包,服务器日志包)

a) 拷贝solr工程

3. commons-lang-2.6.jar工具包,为了能够使用StringUtils工具类

a) 1课前资料jarcommons-lang-2.6.jar

或者拷贝课前资料中已经整理好的jar包到jd工程中

15.4.3. 加入配置文件

不开发dao不需要加入dao相关配置

配置文件加入分析:

Service层:

1.applicationContext-service.xml包扫描器,扫描@service注解的类。

2.applicationContext-solrj.xml配置HttpSolrServer。

Controller层:

1.Springmvc.xml

a) 包扫描器,扫描@Controller注解的类。

b) 配置注解驱动

c) 配置视图解析器

Web.xml文件:

1.配置spring

2.解决post请求乱码的过滤器

3.配置前端控制器。

applicationContext-service.xml

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"

xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

<!-- 配置service扫描 -->

<context:component-scan base-package="cn.com.javahelp.jd.service" />

</beans>

applicationContext-solrj.xml

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"

xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

<!-- 配置HttpSolrServer -->

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

<!-- 配置solr接口地址 -->

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

</bean>

</beans>

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

<!-- 配置Controller扫描 -->

<context:component-scan base-package="cn.com.javahelp.jd.controller" />

<!-- 配置注解驱动 -->

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

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>jd</display-name>

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

<!-- 配置spring -->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:spring/applicationContext-*.xml</param-value>

</context-param>

<!-- 配置监听器加载spring -->

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<!-- 配置拦截器,解决post请求乱码的问题 -->

<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</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

<param-name>contextConfigLocation</param-name>

<!-- 指定springMVC配置文件 -->

<param-value>classpath:spring/springmvc.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>jd</servlet-name>

<!-- 所有以action结尾的请求都进入springmvc -->

<url-pattern>*.action</url-pattern>

</servlet-mapping>

</web-app>

15.4.4. 加入静态资源

解压课前资料的案例

images是案例的商品图片

resource是jd工程的资源文件

WEB-INF里面放的是jsp页面

1. 配置虚拟路径,并把images拷贝到配置的文件夹

2. 复制resource和WEB-INF到工程中

最终效果

15.5. 实现搜索页跳转

编写Controller

@Controller

@RequestMapping("search")

public class SearchController {

@RequestMapping("list")

public String queryProduct() {

return "product_list";

}

}

启动Tomcat,访问效果:

15.6. 创建pojo

分析页面,根据页面需求创建pojo

原则,页面需要什么,就传递什么

15.6.1. 创建商品pojo

分析jsp页面,发现需要展示的商品属性如下

根据页面的需求,创建对应的pojo。

public class Product {

private String pid;

private String name;

private String price;

private String picture;

get/set。。。

}

15.6.2. 创建分页pojo

在页面上搜索上一页,搜索到分页是就是方法实现

搜索js方法,分页数据是从id为page的元素上获取

搜索page元素,分页数据都是result这个对象提供的

根据resul这个分页对象,创建分页pojo

public class Result {

private Integer curPage;// 当前页

private Integer pageCount;// 总页数

private Long recordCount;// 数据总条数

private List<Product> productList;// 商品结果集

get/set。。。

}

15.7. 实现Controller

15.7.1. 分析

我们主要实现搜索功能,Controller需要接收前端提交的参数,把查询到的数据传递到页面上进行展示。

传递到页面的数据前面已经分析了,实际上就是分页对象。现在需要分析页面提交的参数,页面主要是点击搜索按钮,可以在页面中搜索“搜索”:

分析发现,这其实是一个form表单,是一个POST提交的

里面有5个参数,在Controller都应该进行接收。然后调用service的方法,获取返回值,应该是一个Result的分页用的对象。而且这些参数都需要进行回显。

15.7.2. 实现代码

根据以上分析,实现Controller的代码

@Controller

@RequestMapping("search")

public class SearchController {

@Autowired

private SearchService searchService;

/**

* 实现搜索功能

*

* @param model

* @param queryString

* @param catalog_name

* @param price

* @param sort

* @param page

* @return

*/

@RequestMapping("list")

public String queryProduct(Model model, String queryString, String catalog_name, String price, String sort,

Integer page) {

// 根据条件搜索

Result result = this.searchService.queryProduct(queryString, catalog_name, price, sort, page);

// 把结果集放到模型中

model.addAttribute("result", result);

// 搜索条件数据回显

model.addAttribute("queryString", queryString);

model.addAttribute("catalog_name", catalog_name);

model.addAttribute("price", price);

model.addAttribute("sort", sort);

model.addAttribute("page", page);

return "product_list";

}

}

15.8. 实现Service

15.8.1. 实现Service接口

public interface SearchService {

/**

* 根据条件从索引库中查询数据

*

* @param queryString 查询关键词

* @param catalog_name 商品分类

* @param price 商品价格

* @param sort 排序

* @param page 当前页码

* @return

*/

Result queryProduct(String queryString, String catalog_name, String price, String sort, Integer page);

}

15.8.2. 实现service实现类

@Service

public class SearchServiceImpl implements SearchService {

@Autowired

private HttpSolrServer httpSolrServer;

@Override

public Result queryProduct(String queryString, String catalog_name, String price, String sort, Integer page)

throws Exception {

// 创建SolrQuery对象

SolrQuery solrQuery = new SolrQuery();

// 设置查询关键词

if (StringUtils.isNotBlank(queryString)) {

solrQuery.setQuery(queryString);

} else {

solrQuery.setQuery("*:*");

}

// 设置默认域

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

// 设置商品类名过滤条件

// 设置商品分类名称

if (StringUtils.isNotBlank(catalog_name)) {

catalog_name = "product_catalog_name:" catalog_name;

}

// 设置商品价格

if (StringUtils.isNotBlank(price)) {

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

if (sp != null && sp.length == 2) {

price = "product_price:[" sp[0] " TO " sp[1] "]";

}

}

solrQuery.setFilterQueries(catalog_name, price);

// 商品排序,如果是1,正序排序,如果是其他,则倒序排序

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

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

} else {

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

}

// 设置分页

if (page == null) {

page = 1;

}

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

solrQuery.setRows(20);

// 设置高亮

solrQuery.setHighlight(true);

solrQuery.addHighlightField("product_name");

solrQuery.setHighlightSimplePre("<font color=\'red\'>");

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

// 查询数据

QueryResponse response = this.httpSolrServer.query(solrQuery);

// 获取查询总数

SolrDocumentList results = response.getResults();

long total = results.getNumFound();

// 获取高亮数据

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

// 解析结果集,存放到Product中

List<Product> products = new ArrayList<>();

for (SolrDocument solrDocument : results) {

Product product = new Product();

// 商品id

product.setPid(solrDocument.get("id").toString());

// 商品标题,设置高亮

List<String> list = map.get(solrDocument.get("id")).get("product_name");

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

product.setName(list.get(0));

} else {

product.setName(solrDocument.get("product_name").toString());

}

// 商品价格

product.setPrice(solrDocument.get("product_price").toString());

// 商品图片

product.setPicture(solrDocument.get("product_picture").toString());

products.add(product);

}

// 封装返回对象

Result result = new Result();

result.setCurPage(page);

result.setRecordCount(total);

result.setProductList(products);

// 总页数计算公式(total rows-1)/rows

result.setPageCount((int) (total 20 - 1) / 20);

return result;

}

}

15.8.3. 启动Tomcat

访问:http://localhost:8081/jd/list.action

0 人点赞