下载地址: http://archive.apache.org/dist/lucene/solr下载XXX.zip文件
1 . 基本安装步骤:
1 . 解压后将dist/solr-4.9.1.war包复制到tomcat的webapp目录下 , 记得改名 , 以便访问
2 . 赋值solr解压包下example/lib/ext下的所有jar包到tomcat的lib下
3 . 在本地计算机下创建文件夹solr_home
4 . 启动服务器,启动完后关闭服务器,用来解开war包
5 . 并复制example/solr下的文件到solr_home
6 . 修改配置文件webapp/solr/web_inf/web.xml , 增加下面一段
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>盘符:/XX/solr_home</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
7 . 在solr_home下赋值collection1,改名并修改配置文件core.properties
name=文件夹名
8 . 启动tomcat , http://192.168.1.99:8083/solr
显示成功
二 . 新增数据库配置
1 . 复制jar包 mysql-connector-java-5.1.18.jar到Tomcat的lib目录
2 . 新建core , 复制solr_home的collection1文件 , 改名和配置文件
3 . 打开core文件夹conf中的solrconfig.xml文件 , 在requestHandler name="/select" class="solr.SearchHandler">前面加上一个dataimport的处理handler
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
4 . core文件夹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/itrip" user="root" password="root" />
<!---->
<document name="hotel_doc">
<entity name="hotel" pk="id" query=" select id,hotelName,address from itrip_hotel">
<field column="id" name="id" />
<field column="hotelName" name="hotelName" />
<field column="address" name="address" />
</entity>
</document>
</dataConfig>
5 . 修改schema.xml配文
a . 删除除了name=_version_的<field> , 包括动态field<dynamicField>和<copyField>也删除
b . 添加索引字段 : 添加的是data-config.xml相应的字段
<!--type属性传统的数据类型要对应solr对应的数据类型-->
<field name="id" type="int" indexed="true" stored="true"/>
<field name="hotelName" type="string" indexed="true" stored="true"/>
<field name="address" type="string" indexed="true" stored="true"/>
<!--添加额外的标签-->
<field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
6 . 将 /下载\solr-4.9.1\dist目录下 导入数据的jar包拷贝到/webapps/solr/WEB-INF/lib下
solr-dataimporthandler-4.9.1.jar
solr-dataimporthandler-extras-4.9.1.jar
7 . 启动tomcat , 执行数据查询 http://192.168.1.99:8083/solr
报错initializing QueryElevationComponent
查看solr的logging发现报错: Invalid Number : MA147LL/A
这是solr坑 , schema.xml文件的field的id数据类型设置成了int类型,但是solr启动的时候会去conf目录扫描elevate.xml文件 , 这个文件中定义的id类型值是
MA147LL/A , 所有报了上面的错
解决方法 :
将<query text="ipod">
<doc id="MA147LL/A" /> <!-- put the actual ipod at the top -->
<doc id="IW-02" exclude="true" /> <!-- exclude this cable -->
</query>
这段注释掉
3.增量更新
1.solr_home目录下新建conf文件 , 在conf目录下新建dataimport.properties配置文件
#################################################
# #
# dataimport scheduler properties #
# #
#################################################
# to sync or not to sync
# 1 - active; anything else - inactive
syncEnabled=1
# which cores to schedule
# in a multi-core environment you can decide which cores you want syncronized
# leave empty or comment it out if using single-core deployment
#根据现有的core , 用,间隔
syncCores=test,hotel
# solr server name or IP address
# [defaults to localhost if empty]
#主机地址 我的是192.168.1.99
server=localhost
# solr server port
# [defaults to 80 if empty]
port=8083
# application name/context
# [defaults to current ServletContextListener's context (app) name]
webapp=solr
# 增量索引的参数
# URL params [mandatory]
# remainder of URL
params=/dataimport?command=delta-import&clean=false&commit=true
# 重做增量索引的时间间隔
# schedule interval
# number of minutes between two runs
# [defaults to 30 if empty]
interval=1
# 重做全量索引的时间间隔,单位分钟,默认7200,即5天;
# 为空,为0,或者注释掉:表示永不重做索引
#reBuildIndexInterval=7200
# 重做索引的参数
reBuildIndexParams=/dataimport?command=full-import&clean=true&commit=true
# 重做索引时间间隔的计时开始时间,第一次真正执行的时间=reBuildIndexBeginTime+reBuildIndexInterval*60*1000;
# 两种格式:2012-04-11 03:10:00 或者 03:10:00,后一种会自动补全日期部分为服务启动时的日期
reBuildIndexBeginTime=03:10:00
2 . 将apache-solr-dataimportscheduler.src.jar文件(到哪找 , 我也不知道)拷贝到solr的bin
3 . 新增增量更新数据的监听器,在solr的web.xml中加入以下监听器
<listener>
<listener-class>
org.apache.solr.handler.dataimport.scheduler.ApplicationListener
</listener-class>
</listener>
4 . 修改导入数据查询SQL(solr_home\hotel\conf\data-config.xml)
deltaImportQuery="select id,hotelName,address from itrip_hotel where id = '${dih.delta.id}'"
deltaQuery="SELECT id as id FROM itrip_hotel where modifyDate > '${dih.last_index_time}'"
• deltaQuery是根据dataimport.properties配置文件中的更新时间,从数据库中查询出,修改日期在最后一次更新日期之后的酒店数据,并记录其id,而deltaImportQuery的目的是将deltaQuery查询出的数据导入到solr中
启动Tomcat进行测试
– 修改数据库中的酒店数据并同时修改该数据的modifyDate时间
1分钟后查询酒店数据,确定数据是否更新
4 . 全文检索
4.1分词器
solr分词器配置
常见的java分词器有:ansj分词器,word分词器,IKAnalyzer分词器
本次使用IKAnalyzer分词器
版本要严格控制:solr是3.x的版本用IKAnalyzer2012_u6.zip 如果solr是4.x版本用IKAnalyzer2012FF_hf1.zip
下载地址:
1.将ik的所有jar文件拷贝到tomcat的webapp/solr/web-inf/lib下
2.将IKAnalyzer.cfg.xml和stopword.dic文件拷贝到wenapp/solr/web-inf/classes目录下
3.修改solr_home/XXcore/conf/schema.xml配文,增加一个<field>
<!--分词器类型-->
<fieldType name="text_ik" class="solr.TextField">
<!--索引时候的分词器-->
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<!--查询时候的分词器-->
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
4.修改solr_home/XXcore/conf/schema.xml配文,将新增的需要进行模糊查询的type类型修改为text_ik
5.多字段匹配(检索的内容可能出现在多个列字段中)修改solr_home/XXcore/conf/schema.xml配文
<field name="keyword" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<copyField source="hostName" dest="keyword"/>
<copyField source="address" dest="keyword"/>
4.solr查询的结果接受对象
创建查询条件的java对象,属性上加注解solr下面的包@Field(“id”)
5 . 代码实现
下载solrj程序jar包
使用maven依赖方式添加
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>5.3.1</version>
</dependency>
<!--solrj的两个依赖jar包,是日志框架相关的jar包 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
在程序中创建solr查询的接收对象
-
- 对应schema文件-创建Solr查询的接收对象
- 添加Field注解
public class ItripHotelVO implements Serializable {
@Field
private Integer id;
@Field
private String hotelName;
@Field
private String address;
}
编写客户端程序
创建HttpSolrClient对象
创建SolrQuery对象
创建QueryResponse数据接收对象
接收数据,转化数据
@Test
public void test1() {
// 连接url---本地solr访问地址:ip:端口号/solr/模块名
String url = "http://localhost:8080/solr/hotel";
// 创建solrClient
HttpSolrClient solrClient = new HttpSolrClient(url);
// 设置响应的解析器
solrClient.setParser(new XMLResponseParser());
// 设置建立连接的最长时间
solrClient.setConnectionTimeout(5000);
// 定义查询对象solrQuery
SolrQuery solrQuery = new SolrQuery("*:*");
// 设置排序规则
solrQuery.setSort("id", SolrQuery.ORDER.asc);
// 设置起始位置
solrQuery.setStart(0);
solrQuery.setRows(10);
try {
// 得到查询的响应对象
QueryResponse queryResponse = solrClient.query(solrQuery);
// 通过getBeans可以执行查询,将solr中的数据通过.class反射封装到对象中
List<ItripHotelVO> list = queryResponse.getBeans(ItripHotelVO.class);
for (ItripHotelVO hotelVO : list) {
System.out.println(hotelVO.getHotelName());
}
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
dao的封装
- 出口
- controller JSON
- 分层
- 数据访问层
- 通用查询抽取
- 参数抽取
- 数据访问层
- 业务逻辑层
- 表示层
- 抽取baseDao
public class BaseDao<T> {
private HttpSolrClient solrClient;
private QueryResponse queryResponse;
public BaseDao(String url) {
// 创建solrClient
solrClient = new HttpSolrClient(url);
// 设置响应的解析器
solrClient.setParser(new XMLResponseParser());
// 设置建立连接的最长时间
solrClient.setConnectionTimeout(5000);
}
public List<T> queryList(SolrQuery solrQuery, Class clazz) {
List<T> list = new ArrayList<>();
try {
// 得到查询的响应对象
queryResponse = solrClient.query(solrQuery);
// 通过getBeans可以执行查询,将solr中的数据通过.class反射封装到对象中
list = queryResponse.getBeans(clazz);
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
return list;
}
}
}
- 编写具体HotelDao
public class HotelDao extends BaseDao {
private static String url = "http://localhost:8080/solr/hotel";
public HotelDao() {
// 注意,url属性前一定要用static修饰,否则会报错
super(url);
}
public List<ItripHotelVO> queryList(String keyword) {
SolrQuery solrQuery = new SolrQuery("keyword:" + keyword);
// 调用baseDao的queryList方法
List list = this.queryList(solrQuery, ItripHotelVO.class);
return list;
}
}