Solr
目 录
1 solr简介 3
1.1 solr是什么 3
1.2 solr能做什么 3
1.3 为什么需要solr 3
1.4 solr下载路径 4
1.5 solr目录结构说明 4
2 入门示例 5
2.1 需求 5
2.2 配置步骤说明 5
2.3 配置步骤 5
2.4 第一部分:配置solr服务器 5
2.4.1 第一步:解压一个tomcat 5
2.4.2 第二步:部署solr服务到tomcat中 5
2.4.3 第三步:添加solr运行依赖的jar包 6
2.5 第二部分:配置solrhome 6
2.5.1 第一步:拷贝到本地,修改名称为solrhome。(见名知意) 7
2.5.2 第二步:配置solrcore 7
2.6 第三部分:在solr服务器中加载solrhome 9
2.6.1 第一步:修改web.xml加载solrhome 9
2.6.2 第二步:启动tomcat测试 10
2.7 第四部分:创建java程序访问solr服务器 10
2.7.1 第一步:创建项目,导入jar包 11
2.7.2 第二步:创建索引 11
2.7.3 第三步:搜索索引 19
3 solr管理控制台 21
3.1 查询界面说明 21
3.2 安装dataimport插件 24
3.2.1 dataimport插件说明 24
3.2.2 安装步骤 25
3.3 analyzer分析器,配置中文分词器 27
3.3.1 solr自带分词器的缺陷 27
3.3.2 solr配置中文分析器 27
4 solr案例实战 30
4.1 需求 30
4.2 分析 30
4.2.1 ui分析 30
4.2.2 架构分析 31
4.3 环境准备 31
4.4 功能开发 32
4.4.1 第一步:创建web工程,导入jar包 32
4.4.2 第二步:代码实现 33
4.4.3 第三步:spring整合solr、springmvc 40
4.5 启动web应用程序,测试 43
4.5.1 注意事项 43
4.5.2 修改solr服务器的tomcat的端口 43
4.5.3 修改springmvc.xml 43
4.5.4 访问搜索页面 44
1 solr简介
1.1 solr是什么
solr是一个基于全文检索的企业级应用服务器。
全文检索:可以输入一段文字,通过分词检索数据!!(复习)
应用服务器:它是单独的服务。
1.2 solr能做什么
它就是用于做全文搜索。
1.3 为什么需要solr
问题:我们已经学过lucene,为什么还要学习solr?
答:lucene是一个工具包,不能单独运行,需要导入到java代码中。
solr可以独立运行在tomcat容器中,通过http协议,以接口的方式对外提供服务,java代码只需要专注于业务的处理就可以。
1.4 solr下载路径
solr是基于lucene实现的,和lucene同步更新。
1.5 solr目录结构说明
下载solr-4.10.3.zip并解压:
bin:solr的运行脚本
contrib:solr的一些扩展jar包,用于增强solr的功能。
dist:该目录包含build过程中产生的war和jar文件,以及相关的依赖文件。
docs:solr的api文档
example:solr工程的例子目录:
licenses:solr相关的一些许可信息
2 入门示例
2.1 需求
使用solr实现电商网站的商品搜索功能。
2.2 配置步骤说明
(1)配置solr服务器。
(2)配置solrhome。(solr服务的主目录,磁盘)
(3)在solr服务器中加载solrhome。
(4)java程序访问solr服务器,实现全文搜索。
2.3 配置步骤
2.4 第一部分:配置solr服务器
--说明:solr可以独立运行,需要servlet容器加载它。本文使用tomcat。
2.4.1 第一步:解压一个tomcat
解压一个新的tomcat,专门用来加载solr。
|
2.4.2 第二步:部署solr服务到tomcat中
--在solr的下载包中,提供了solr的war包程序。(空的war包程序)
|
--拷贝solr.war到tomcat的webapp目录下。并解压
|
2.4.3 第三步:添加solr运行依赖的jar包
--在solr的下载包中,提供solr服务器运行所依赖的jar包。
|
(1)拷贝/example/lib/ext下的所有包,到solr应用的lib目录中
|
(2)拷贝/example/resource/log4j.properties,到solr应用的classes目录下。
--前提:先在/web-inf/目录下,创建classes目录。
|
2.5 第二部分:配置solrhome
--说明:solr的下载包中,提供了标准的solrhome配置。
|
2.5.1 第一步:拷贝到本地,修改名称为solrhome。(见名知意)
|
2.5.1.1 solrhome说明
--solrhome目录结构:
|
(1)solrhome是solr配置搜索服务的主目录。
(2)collection1称为solr服务的一个实例(solrcore)。
(3)一个solr实例对应一个索引库。
(4)solr可以同时配置多个实例。以便为不同的java程序提供搜索服务。
配置solr服务,就是在配置solr实例。
2.5.2 第二步:配置solrcore
2.5.2.1 step1:配置solrcore实例的名称
--说明:每一个实例都有自己的名称。在core.properties文件中配置
|
--在这里,我们将其修改为:sorecore0719
|
2.5.2.2 step2:配置solrcore所需的jar依赖
--说明:solr下载包中,提供solrcore所需要的所有jar依赖。
|
(1)在solrhome同级目录下,创建depjar文件夹。(目的:方便管理jar依赖)
|
(2)拷贝contrib、dist两个目录到depjar目录下。
|
(3)修改/collection1/conf目录下的solrconfig.xml,加载jar包
--说明:solr是通过<lib>标签,来加载运行所需要的jar包的。
|
(4)配置索引库目录
--说明:solr是通过<datadir>标签,来指定索引库的目录的。
|
--默认路径是在solrcore目录下,跟conf目录同级。首次加载时,将自动创建。
|
本课程就使用该默认路径。
2.6 第三部分:在solr服务器中加载solrhome
2.6.1 第一步:修改web.xml加载solrhome
--在solr的应用中,是通过web.xml来加载solrhome的。
|
--说明:在这里是通过修改<env-entry>标签,来加载solrhome的。
|
2.6.2 第二步:启动tomcat测试
--访问地址 http://localhost:8080/solr
|
--solr服务器配置成功!!!
2.7 第四部分:创建java程序访问solr服务器
--前提:创建好了数据库。(导入products-solr.sql文件即可)
|
--配置步骤说明:
(1)创建项目。
(2)创建索引
(3)搜索索引
2.7.1 第一步:创建项目,导入jar包
--导包说明:
solrj核心包 /solr-4.10.3/dist/solr-solrj-4.10.3.jar solrj依赖包 /solr-4.10.3/dist/solrj-lib下的所有包 日志依赖包 /solr-4.10.3/example/lib/ext目录下的所有jar包 jdbc驱动包 mysql-connector-java-5.1.10-bin.jar |
--拷贝log4j.properties到src目录下。(或者创建一个source folder)
--项目结构:
|
2.7.2 第二步:创建索引
--步骤说明。(复习回顾)
(1)采集数据。
(2)将数据转换成solr文档。
(3)连接solr服务器,将文档写入索引库。
2.7.2.1 step1:采集数据
--需求采集的字段说明:
参与搜索的字段:名称、价格、商品类别、描述信息
参与结果展示的字段:商品id、图片、
(1)创建product类
public class product {
private integer pid;
private string name;
private string catalog_name;
private double price;
private string description;
private string picture;
// 补全get、set方法 } |
(2)创建productdao类
package cn.gzsxt.solr.dao;
import java.sql.connection; import java.sql.drivermanager; import java.sql.preparedstatement; import java.sql.resultset; import java.sql.sqlexception; import java.util.arraylist; import java.util.list;
import cn.gzsxt.solr.pojo.product;
public class productdao {
private connection connection; private preparedstatement pst; private resultset rs;
/** * 采集数据,查询所有商品 * @return */ public list<product> getallproducts() {
list<product> products = new arraylist<>();
try {
//1、加载驱动 class.forname("com.mysql.jdbc.driver"); //2、获取connection连接 connection = drivermanager.getconnection("jdbc:mysql://localhost:3306/solr", "root", "gzsxt"); //3、获取preparedstatement,执行预编译 pst = connection.preparestatement("select pid,name, catalog_name,price,description,picture from products"); //4、执行sql搜索 rs = pst.executequery();
product p = null; while(rs.next()){ p = new product(); p.setpid(rs.getint("pid")); p.setname(rs.getstring("name")); p.setprice(rs.getfloat("price")); p.setpicture(rs.getstring("picture")); p.setdescription(rs.getstring("description")); p.setcatalog_name(rs.getstring("catalog_name"));
products.add(p); }
} catch (exception e) { e.printstacktrace(); }finally { if(null!=rs){ try { rs.close(); } catch (sqlexception e) { // todo auto-generated catch block e.printstacktrace(); } } if(null!=pst){ try { pst.close(); } catch (sqlexception e) { // todo auto-generated catch block e.printstacktrace(); } } if(null!=connection){ try { connection.close(); } catch (sqlexception e) { // todo auto-generated catch block e.printstacktrace(); } } }
return products; }
}
|
(3)创建一个测试类productdaotest
--导入junit类库。(快捷键ctrl+1)
package cn.gzsxt.solr.test;
import org.junit.test;
import cn.gzsxt.solr.dao.productdao;
public class productdaotest {
@test public void getallproducts(){ productdao dao = new productdao(); system.out.println(dao.getallproducts()); } } |
--测试结果,采集数据成功!!!
|
2.7.2.2 step2:将数据转换成solr文档solrinputdocument
--说明:solr是通过solrinputdocument来封装数据的。部分源码如下:
public solrinputdocument(map fields){ _documentboost = 1.0f; _fields = fields; }
public void addfield(string name, object value){ addfield(name, value, 1.0f); } |
问题:我们在lucene中知道,域有三大属性,在创建文档的时候指定。而solr的源码中,只是用一个map集合来封装域的信息。那域的三大属性怎么定义呢?
答:solr是通过一个配置文件schema.xml,事先定义域的信息的。
2.7.2.2.1 solr域的说明
--通过<field>标签定义域的名称等信息
|
name属性:域的名称
type属性: 域的类型(<fieldtype>标签,加载了分词器,指定了分词属性)
indexed属性:是否索引
stored属性:是否存储
multivalued属性:是否支持多个值
--通过<fieldtype>标签,定义域的类型信息
|
name属性:域类型的名称
class属性:指定域类型的solr类型。
<analyzer>:指定分词器。
<analyzer type=”index”>:表示在创建索引时,对域做分词处理。
<analyzer type=”query”>:表示在检索索引时,对域做分词处理。
<tokenizer>标签:指定分词器
<filter>标签:指定过滤器
2.7.2.2.2 solr域的特点
(1)、solr的域必须先定义,后使用。(否则报错:unknown fieldname)
(2)、定义solr域的时候,必须指定是否索引、是否存储这两个属性。<field>
(3)、定义solr域的时候,必须指定域的类型<fieldtype>:
因为域的类型确定了这个域在索引、搜索两个阶段的分词属性。
<field>标签: 来指定索引、存储两个属性
<fieldtype>标签:来指定分词属性
(4)、每一个文档中,必须包含id这个域,它的值标记文档的唯一性。
|
2.7.2.2.3 配置solr业务域
--商品各字段属性说明
域 |
tokened |
indexed |
stored |
商品的id |
n |
y |
y |
商品的名称 |
y |
y |
y |
商品的类别 |
n |
y |
y |
商品的价格 |
y |
y |
y |
商品的图片 |
n |
n |
y |
商品描述信息 |
y |
y |
n |
--修改schema.xml,添加如下配置。(id域不用配置,直接使用solr的id域)
<!--product--> <field name="id" type="string" indexed="true" stored="true" required="true" multivalued="false" /> <field name="product_name" type="text_general" indexed="true" stored="true"/> <field name="product_catalog_name" type="string" indexed="true" stored="true" /> <field name="product_price" type="double" indexed="true" stored="true"/> <field name="product_description" type="text_general" indexed="true" stored="false" /> <field name="product_picture" type="string" indexed="false" stored="true" /> |
2.7.2.2.4 修改productdao,新增getdocuments方法
/** * 将采集到的商品数据,转换成solr文档类型 * @param products * @return */ public list<solrinputdocument> getdocuments(list<product> products){ list<solrinputdocument> docs = new arraylist<>(); solrinputdocument doc = null; for (product product : products) { doc = new solrinputdocument(); doc.addfield("id", product.getpid()); doc.addfield("product_name", product.getname()); doc.addfield("product_price", product.getprice()); doc.addfield("product_catalog_name", product.getcatalog_name()); doc.addfield("product_description", product.getdescription()); doc.addfield("product_picture", product.getpicture());
docs.add(doc); }
return docs; } |
2.7.2.3 step3:连接solr服务器,创建索引
--前提:已经启动了tomcat,加载了solr服务器。(前面给过schema.xml,需要重写启动tomcat)
--修改productdaotest类,新增createindex方法
@test public void createindex(){ // 1、 创建httpsolrserver对象,通过它和solr服务器建立连接。 // 参数:solr服务器的访问地址 httpsolrserver server = new httpsolrserver("http://localhost:8080/solr/solrcore0719"); // 2、 通过httpsolrserver对象将solrinputdocument添加到索引库。 productdao dao = new productdao(); try { server.add(dao.getdocuments(dao.getallproducts())); // 3、 提交。 server.commit(); system.out.println("创建索引库成功!!!");
} catch (solrserverexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } } |
2.7.2.4 step4:访问solr主界面,在query选项下测试
|
--创建索引库成功!!!
2.7.3 第三步:搜索索引
--修改productdaotest类型,新增一个查询方法
@test public void queryindex() throws exception { // 创建httpsolrserver对象,通过它和solr服务器建立连接。 // 参数:solr服务器的访问地址 httpsolrserver server = new httpsolrserver("http://localhost:8080/solr/solrcore0719");
// 创建solrquery对象 solrquery query = new solrquery(); // 设置查询条件,参考主界面 query.set("q", "*:*");
// 调用server的查询方法,查询索引库 queryresponse response = server.query(query);
// 查询结果 solrdocumentlist results = response.getresults();
// 查询结果总数 long cnt = results.getnumfound(); system.out.println("查询结果总数:" + cnt);
system.out.println("--------------------分隔符-------------------");
for (solrdocument solrdocument : results) { system.out.println("商品id:"+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"));
system.out.println("----------------------------------------"); } } |
--查询结果,非常成功!!!
|
3 solr管理控制台
3.1 查询界面说明
|
(1) q - 查询关键字,必须,如果查询所有文档时,使用*:*。
|
(2) fq - (filter query)过虑查询,可以有多个。如:价格10到50的记录。
|
(3) sort - 排序,格式:sort=<field name>+<desc|asc>。如:按价格升序
|
(4) start - 分页显示使用,开始记录下标,从0开始
|
(5) rows - 指定返回结果最多有多少条记录,配合start来实现分页。
|
(6) fl - 指定返回那些字段内容,用逗号或空格分隔多个。
|
(7) df-指定一个默认搜索的field
|
(8) wt - (writer type)指定输出格式,默认json格式。
|
3.1.1 对照界面,实现复杂查询
--修改productdaotest类型,新增动态查询方法
@test public void querydynamic(){ //1、连接solr服务器 httpsolrserver server = new httpsolrserver("http://localhost:8080/solr/solrcore0719");
//2、创建查询对象,封装查询条件 solrquery query = new solrquery(); //设置默认搜索的域 query.set("df", "product_name");
//参考管理界面中的 "q"标签,封装查询的关键词 query.set("q", "音乐盒");
//添加价格过滤 query.addfilterquery("product_price:[10 to 50]"); //添加类别过滤 query.addfilterquery("product_catalog_name:幽默杂货");
//设置排序 价格升序 query.set("sort","product_price asc");
//设置分页信息 第二页 每页10条 start=(page-1)*pagesize query.set("start", 10); query.set("rows",10);
//设置要查询字段 query.set("fl", "id,product_name,product_price");
//3、执行查询 try { queryresponse response = server.query(query);
//获取查询的响应码 int status = response.getstatus(); system.out.println("响应码:"+status);
if(0==status){ solrdocumentlist solrdocumentlist = response.getresults();
long numfound = solrdocumentlist.getnumfound(); system.out.println("共查询到"+numfound+"条满足条件的数据!"); system.out.println("--------------"); for (solrdocument s : solrdocumentlist) { system.out.println("商品的id:"+s.get("id")); system.out.println("商品的名称:"+s.get("product_name")); system.out.println("商品的价格:"+s.get("product_price")); system.out.println("商品的图片:"+s.get("product_picture")); system.out.println("商品的类别名称:"+s.get("product_catalog_name")); system.out.println("商品的描述:"+s.get("product_decsription")); system.out.println("-----------分隔符---------------"); }
}
} catch (solrserverexception e) {
e.printstacktrace(); } } |
--测试结果:非常成功!!!(对比管理界面查询结果)
|
3.2 安装dataimport插件
3.2.1 dataimport插件说明
--好处:可以在管理界面直接从数据库导入数据到索引库。(即:一个插件解决入门示例中,创建索引的全部操作)
|
3.2.2 安装步骤
3.2.2.1 第一步:添加jar依赖
(1)将/solr-4.10.3/dist/solr-dataimporthandler-4.10.3.jar拷贝到
/depjar/contrib/dataimporthandler/lib目录下
|
(2)、将jdbc驱动包拷贝到 /depjar/contrib/db/lib 目录下
|
(3)、在solrconfig.xml文件中,加载这两个jar依赖
<lib dir="f:/depjar/contrib/dataimporthandler/lib/" regex=".*\.jar" /> <lib dir="f:/depjar/contrib/db/lib/" regex=".*\.jar" /> |
3.2.2.2 第二步:配置数据库表和solr域的映射关系
--在solr实例的conf目录下,配置数据库映射文件data-config.xml
<?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="gzsxt"/> <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" 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.2.2.3 第三步:创建dataimport处理器
--说明:solr是在solrconfig.xml文件中,通过<requesthandler>标签定义各类请求处理器
--修改solrconfig.xml,添加如下配置。(加载data-config.xml映射文件)
<requesthandler name="/dataimport" class="org.apache.solr.handler.dataimport.dataimporthandler"> <lst name="defaults"> <str name="config">data-config.xml</str> </lst> </requesthandler> |
3.2.2.4 第四步:重启tomcat,在管理界面测试
--测试清空索引库,成功!!!
|
--测试重新导入数据,成功!!!
|
3.3 analyzer分析器,配置中文分词器
3.3.1 solr自带分词器的缺陷
--solr跟lucene一样,提供了很多分析器。可以在analyzer选型下测试分词效果。
|
--测试发现:所以的分词器,对中文支持都不友好。
解决办法:配置中文分词器。
3.3.2 solr配置中文分析器
3.3.2.1 中文分析器选择
选择ik中文分词器。
3.3.2.2 配置步骤
3.3.2.2.1 第一步:添加ikanalyze的jar依赖
--把ikanalyzer2012ff_u1.jar添加到solr/web-inf/lib目录下。
3.3.2.2.2 第二步:加载ikanalyzer的核心配置文件
--拷贝ikanalyzer的配置文件到solr/web-inf/classes目录
|
3.3.2.2.3 第三步:创建中文分词器
--在schema.xml中自定义一个fieldtype,指定中文分词器ikanalyzer。
<!-- ikanalyzer--> <fieldtype name="text_ik" class="solr.textfield"> <analyzer class="org.wltea.analyzer.lucene.ikanalyzer"/> </fieldtype> |
3.3.2.3 测试中文分词器
3.3.2.3.1 第一步:重启tomcat
3.3.2.3.2 第二步:在analysis选项卡下,测试分词效果。成功!!!
|
3.3.3 改造业务域,使用ik做分词器
--修改schem.xml文件,修改需要分词的域的fieldtype类型
我们只需要修改product_name、product_description两个业务域即可。
<field name="id" type="string" indexed="true" stored="true" required="true" multivalued="false" />
<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="double" 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" /> |
--重启tomcat即可。
4 solr案例实战
4.1 需求
使用solr实现电商网站中商品信息搜索功能,可以根据关键字、分类、价格搜索商品信息,也可以根据价格进行排序,并且实现分页功能。
界面如下:
4.2 分析
开发人员需要的文档:静态页面(根据ui设计由美工给出)、数据库设计、原型设计
4.2.1 ui分析
4.2.2 架构分析
架构分为:
(1)、solr服务器。(已经做完,同入门示例)
(2)、自己开发的应用(重点)
(3)、数据库mysql
自己开发的应用
controller 负责和前端页面进行请求和响应的交互
service 封装查询条件,调用dao。
dao 搜索索引库,返回搜索结果。
4.3 环境准备
solr:4.10.3
jdk环境:1.7.0_72(solr4.10 不能使用jdk1.7以下)
ide环境:eclipse
web服务器(servlet容器):tomcat 7x
4.4 功能开发
4.4.1 第一步:创建web工程,导入jar包
|
--导入的jar包说明:
solrj的包
solr服务的日志包
spring的包(包含springmvc)
核心包 4个 core 、bean、context、expresstion
注解包 aop
web包 web、webmvc
commons日志包 common-logging
jstl包
--导入静态资源和jsp页面说明:
静态资源放在webapp目录下,jsp页面放到/web-inf/目录下
4.4.2 第二步:spring整合solr、springmvc
4.4.2.1 创建springmvc.xml
在config包下,创建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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd "> <!-- 配置扫描包 --> <context:component-scan base-package="cn.gzsxt" /> <!-- 配置注解驱动 --> <mvc:annotation-driven />
<!-- jsp视图解析器 --> <bean class="org.springframework.web.servlet.view.internalresourceviewresolver"> <!-- 前缀 --> <property name="prefix" value="/web-inf/jsp/"></property> <!-- 后缀 --> <property name="suffix" value=".jsp"></property> </bean> <bean class="org.apache.solr.client.solrj.impl.httpsolrserver"> <constructor-arg value="http://localhost:8080/solr/solrcore0719"></constructor-arg> </bean>
</beans> |
4.4.2.2 创建web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="webapp_id" version="3.1"> <display-name>jd0719</display-name>
<!-- springmvc配置 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class> <init-param> <param-name>contextconfiglocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>character 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>character encoding</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping> </web-app> |
4.4.3 第三步:整合测试
4.4.3.1 需求:
访问搜索页面。
4.4.3.2 创建pagecontroller类
package cn.gzsxt.solr.controller;
import org.springframework.stereotype.controller; import org.springframework.web.bind.annotation.pathvariable; import org.springframework.web.bind.annotation.requestmapping;
@controller public class pagecontroller {
@requestmapping(value="/{page}") public string showpage(@pathvariable("page")string page){
return page; } } |
4.4.3.3 注意事项
(1)solr服务器要先开启。
(2)solr服务器部署的tomcat和本web应用的部署的tomcat不是同一个。
(3)要同时启动两个tomcat,要注意端口冲突问题。
4.4.3.4 修改solr服务器的tomcat的端口
--在server.xml文件中,修改端口
--tomcat端口说明:
8005:关机端口
8080:默认服务端口
8009:请求转向端口。
--注意:这三个端口都需要修改。不然启动会冲突
本次课程中,将solr的tomcat端口,修改为8888.
4.4.3.5 修改springmvc.xml
--修改solr服务的端口
<bean class="org.apache.solr.client.solrj.impl.httpsolrserver"> <constructor-arg value="http://localhost:8888/solr/solrcore0719"></constructor-arg> </bean>
|
4.4.3.6 访问搜索页面
地址:
|
整合成功!!!
4.4.4 第四步:搜索功能实现
分析代码结构:
请求路径 |
list.action |
请求方式 |
post |
请求参数 |
querystring、catalog_name、price、curpage、sort(共5个) |
返回结果 |
定义product 以及productmodel |
4.4.4.1 pojo
4.4.4.1.1 分析
结合查询界面,分析得出:
--需要一个商品的pojo(product),存放商品信息
--需要一个包装pojo(resultmodel),它包括商品列表信息、商品分页信息
4.4.4.1.2 创建product类
public class product { // 商品编号 private string pid; // 商品名称 private string name; // 商品分类名称 private string catalog_name; // 价格 private double price; // 商品描述 private string description; // 图片名称 private string picture; } |
4.4.4.1.3 创建resultmodel类
public class resultmodel { private list<product> productlist; // 商品总数 private long recordcount; // 总页数 private int pagecount; // 当前页 private int currentpage; } |
4.4.4.2 dao
4.4.4.2.1 功能
接收service层传递过来的参数,根据参数查询索引库,返回查询结果。
4.4.4.2.2 创建productdao接口,定义一个查询方法
public interface productdao {
//查询商品信息,包括分页信息 public resultmodel queryproduct(solrquery query) throws exception; } |
4.4.4.2.3 创建productdaoimpl,重新改查询方法
package cn.gzsxt.dao.impl;
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.impl.httpsolrserver; 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.gzsxt.bean.product; import cn.gzsxt.bean.resultmodel; import cn.gzsxt.dao.productdao;
@repository public class productdaoimpl implements productdao {
@autowired private httpsolrserver server;
@override public resultmodel queryproduct(solrquery query) throws exception { resultmodel result = new resultmodel(); // 通过server查询索引库 queryresponse response = server.query(query); // 获得查询结果 solrdocumentlist documentlist = response.getresults(); // 把查询结果总数设置到resultmodel result.setrecordcount(documentlist.getnumfound());
list<product> productlist = new arraylist<>(); product product = null; // 高亮信息 map<string, map<string, list<string>>> highlighting = response .gethighlighting(); for (solrdocument solrdocument : documentlist) { product = new product(); product.setpid((string) solrdocument.get("id"));
string prodname = (string) solrdocument.get("product_name");
list<string> list = highlighting.get(solrdocument.get("id")).get( "product_name"); if (list != null) prodname = list.get(0);
product.setname(prodname); product.setcatalog_name((string) solrdocument .get("product_catalog_name")); product.setprice((float) solrdocument.get("product_price")); product.setpicture((string) solrdocument.get("product_picture"));
productlist.add(product); }
// 把商品列表放到resultmap中 result.setproductlist(productlist); return result; }
} |
4.4.4.3 service
4.4.4.3.1 功能分析
接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。
接收返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。
4.4.4.3.2 创建productservice接口,定义一个查询方法
public interface productservice { public resultmodel queryproduct(string querystring, string cataname, string price, string sort, integer curpage) throws exception; } |
4.4.4.3.3 创建productserviceimpl类,重写改查询方法
package cn.gzsxt.service.impl;
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.gzsxt.dao.productdao; import cn.gzsxt.service.productservice; import cn.gzsxt.vo.resultmodel;
@service public class productserviceimpl implements productservice {
@autowired private productdao productdao; @override public resultmodel queryproduct(string querystring, string cataname, string price, string sort, integer curpage) throws exception {
//封装查询条件 solrquery query = new solrquery();
//判断查询条件是否为空 if(!"".equals(querystring)&& null != querystring){ query.setquery(querystring); }else{ query.setquery("*:*"); }
//判断过滤条件是否为空 if(!"".equals(cataname)&& null !=cataname){ query.addfilterquery("product_catalog_name:"+cataname); }
//判断商品价格是否为空 if(!"".equals(price) && null != price){ string[] prices = price.split("-"); if(prices.length == 2){ query.addfilterquery("product_price:["+prices[0]+" to "+prices[1]+"]"); } }
//设置排序 if("1".equals(sort)){ query.setsort("product_price", order.desc); }else { query.setsort("product_price", order.asc); }
//设置分页信息 if(null == curpage){ curpage = 1; } query.setstart((curpage-1)*20); query.setrows(20); //每页20条数据
//设置默认搜索域 query.set("df","product_name");
query.sethighlight(true); query.addhighlightfield("product_name"); query.sethighlightsimplepre("<font style=\"color:red\">"); query.sethighlightsimplepost("</font>");
resultmodel result = productdao.queryproduct(query); result.setcurrentpage(curpage); // 总页数 = 总数量 / 每页数据条数 结果向上取整 double ceil = math.ceil(result.getrecordcount().doublevalue()/20); result.setpagecount((int)ceil);
return result; } } |
4.4.4.4 controller
4.4.4.4.1 创建productcontroller类,定义查询接口
package cn.gzsxt.controller;
import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.controller; import org.springframework.ui.modelmap; import org.springframework.web.bind.annotation.requestmapping;
import cn.gzsxt.service.productservice; import cn.gzsxt.vo.resultmodel;
@controller public class productcontroller {
@autowired private productservice productservice;
@requestmapping("/list.action") public string queryproduct(string querystring, string catalog_name, string price, string sort, integer curpage, modelmap model) throws exception {
resultmodel resultmodel = productservice.queryproduct(querystring, catalog_name, price, sort, curpage); model.addattribute("result", resultmodel); model.addattribute("querystring", querystring); model.addattribute("catalog_name", catalog_name); model.addattribute("price", price); model.addattribute("sort", sort); model.addattribute("page", curpage);
return "product_list"; } } |
4.4.4.5 测试搜索功能
地址:
|
推荐阅读
-
详解java整合solr5.0之solrj的使用
-
solr在java中的使用实例代码
-
在Eclipse中运行Solr 基础知识
-
java实现简单的solr查询
-
在Python的gevent框架下执行异步的Solr查询的教程
-
python 动态迁移solr数据过程解析
-
JAVAEE——宜立方商城07:Linux上搭建Solr服务、数据库导入索引库、搜索功能的实现
-
Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第九集-补充-之安装jdk】
-
Solr学习笔记---部署Solr到Tomcat上,可视化界面的介绍和使用,Solr的基本内容介绍,SolrJ的使用
-
linux环境下解决solr7.4服务器多表导入数据覆盖的问题