Solr 学习心得
前言
感谢关注本文,希望能为你带来帮助。
本文主要针对7.7.2版本进行讲解,基于windows环境进行操作。
主要分享的部分有
1.Solr基于Tomcat环境的搭建;
2.Mysql数据的导入;
3.增量与全量;
4.定时增量查询与全量查询;
5.Solr集成SpringBoot
6.个人使用过程中的心得
1.Solr介绍
百度百科:Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。
Solr是一款采用java 语言编写,基于Apache Lucene(非常优秀的开源搜索引擎)开发的搜索WEB服务器,面向与企业级的应用,支持XML,JSON等多种数据格式,并嵌套jetty运行容器。它的强大之处用于全文检索,命令突出显示,可提供分布式搜索和索引,并被世界主流互联网企业网站广泛使用。
2.Solr环境搭建
Windows10,Jdk1.8,Tomcat8.5,Solr7.7.2
准备工作
下载地址:https://www.apache.org/dyn/closer.lua/lucene/solr/7.7.2/solr-7.7.2.zip
1.将下载好的Solr压缩文件到本地安装目录,并进行解压。
2.解压之后,将(E:\Solr\solr-7.7.2\solr-7.7.2\server\solr-webapp)下的webapp文件存放到apache-tomcat-8.5.38\webapps目录下并命名为solr
3.与(Solr同级)并建立solr-home目录,并将solr-7.7.2\server的Solr文件拷贝到建立的solr-home目录下。
4.进入apache-tomcat-8.5.38\webapps\solr\WEB-INF目录,并打开web.xml文件。
5.找到并注释以下代码块:
<!--<security-constraint>
<web-resource-collection>
<web-resource-name>Disable TRACE</web-resource-name>
<url-pattern>/</url-pattern>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Enable everything but TRACE</web-resource-name>
<url-pattern>/</url-pattern>
<http-method-omission>TRACE</http-method-omission>
</web-resource-collection>
</security-constraint> -->
6. 添加以下配置:
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<!-- 出处为solr-home的存放路径 -->
<env-entry-value>E:\Solr\solr-home</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
7.打开(E:\Solr\solr-7.7.2\solr-7.7.2\server\lib)目录,引入所有以metrics开头的jar包文件,存放到(E:\tomcat\apache-tomcat-8.5.38-windows-x64\apache-tomcat-8.5.38\webapps\solr\WEB-INF\lib)目录下。
并将(E:\Solr\solr-7.7.2\solr-7.7.2\server\lib\ext)目录下所有jar文件存放到(E:\tomcat\apache-tomcat-8.5.38-windows-x64\apache-tomcat-8.5.38\webapps\solr\WEB-INF\lib)目录下。
运行Tomcat
并访问链接:http://localhost:8080/solr/index.html#/,出现如下图表示安装成功。
3.数据导入
到E:\Solr\solr-7.7.2\solr-7.7.2\dist目录下将
solr-dataimporthandler-7.7.2,
solr-dataimporthandler-extras-7.7.2
两个jar包放在(E:\tomcat\apache-tomcat-8.5.38-windows-x64\apache-tomcat-8.5.38\webapps\solr\WEB-INF\lib)目录下,
并将mysql-connector-java-8.0.16驱动包同时引入。
添加core
进入E:\Solr\solr-7.7.2\solr_home文件夹下,并创建dictionary_core文件夹。
进入(E:\Solr\solr-7.7.2\solr_home\configsets\_default)下,并将conf文件拷贝到instanceDir自定义目录下。
添加Core Admin
name:dictionary_core(自定义)
instanceDir:dictionary_core安装目录
config:默认
schema:默认
在dictionary_core 文件夹下添加data-config配置文件,并添加配置数据源,以及表字段与solr字段的映射:
<dataConfig>
<dataSource
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/dictionary?serverTimezone=GMT%2B8"
user="root"
password="root" />
<document>
<entity name="city_01" query="SELECT city_code,city_name,parent_id FROM city" pk = "id"
deltaImportQuery="select city_code,city_name,parent_id from city where id = ${dataimporter.delta.id}"
deltaQuery="SELECT id FROM people WHERE update_time > ${dataimporter.delta.last_update_time}">
<field column="id" name="id" />
<field column="city_code" name="cityCode" />
<field column="city_name" name="cityName" />
<field column="parent_id" name="parentId" />
</entity>
</document>
</dataConfig>
进入(E:\Solr\solr-7.7.2\solr_home\dictionary_core\conf)目录,修改solrconfig文件指定数据源配置文件的路径:
添加数据源文件配置
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
重启Tomcat
执行execute,表示数据导入成功。
打开Dataimport,打开Configuration查看映射字段
配置Schema,配置映射字段
注:像id,name在solr里属于关键字段。所以在配置时,可以直接无需配置。否则会出现异常提示。
添加映射字段
将数据库表的字段与solr添加映射
往please select …输入刚刚添加的映射字段,查看并显示出来。
再次执行dataimport,显示新增的总记录数
点击query,查询导入成功的数据,显示对应的列名,以及刚刚出现出来的总数。
numFound:表示当前Core的总数量
http://localhost:8080/solr/dictionary_core/select?q=%3A表示执行的命令。
start:0表示起始位置 rows:查询的行数,默认10条
fq:表示查询条件,类似与Sql语句中的where,* 北京 *表示 like %北京%
4.Solr的增量与全量
#增量# :在原有记录上,查询新增的数据,而不是每次查询都查询所有的数据。有利于节省性能。
#全量#:每次查询都往数据库表,查询所有的数据。保障每次更新的数据都是最新的数据。
<dataConfig>
<dataSource
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/dictionary?serverTimezone=GMT%2B8"
user="root"
password="root" />
<document>
<entity name="city_001" query="SELECT id, city_code,city_name,parent_id FROM city_001" pk = "id"
deltaImportQuery="select id, city_code,city_name,parent_id from city_001 where id = ${dataimporter.delta.id}"
deltaQuery="SELECT id,city_code,city_name,parent_id FROM city_001 WHERE update_time > ${dataimporter.delta.last_update_time}">
<field column="id" name="id" />
<field column="city_code" name="cityCode" />
<field column="city_name" name="cityName" />
<field column="parent_id" name="parentId" />
</entity>
</document>
</dataConfig>
dataSource:表示连接的数据源
entity:看成实体类
name:表名
pk:表示主键
query:表示全量查询
daltaImportQuery:表示增量查询并导入
daltalQuery:增量查询
数据库表,添加update_time字段,并设置类型为timestamp,不为null,默认为CURRENT_TIMESTAMP,根据当前时间戳更新。
#deltaQuery# 每次查询时,根据Solr中的配置${dataimporter.delta.last_update_time}去与数据库表的字段做比较,数据库表更新时间大于Solr配置文件中的dataimporter.delta.last_update_time,
E:\Solr\solr-7.7.2\solr_home\dictionary_core\conf\dataimport.properties
#deltaImportQuery# 根据主键id作为查询条件,将查询的数据保存在本地并建立索引。
E:\Solr\solr-7.7.2\solr_home\dictionary_core\data\index
Solr Admin
全量操作
选择full-import,并勾选clear,Commit表示清除本地并更新,执行操作Excute,并刷新状态(Refresh status)。
增量操作
选择delta-import(不要勾选clear,否则会清除已有数据),执行操作Excute,并刷新状态(Refresh status)。
定时增量更新、全量更新
之前所演示的都是根据 SolrAdmin手动去更新,在真实项目中,我们是通过定时任务去完成。
引入apache-solr-dataimportscheduler-1.4.jar,下载地址:
参考博客:https://blog.csdn.net/studententity/article/details/93975400
下载链接:https://pan.baidu.com/s/1rUcIYsiQrOyHbXem0jkNjQ 提取码6hts
修改(E:\tomcat\apache-tomcat-8.5.38\webapps\solr\WEB-INF\web.xml)配置文件并添加监听器:
<listener>
<listener-class>
org.apache.solr.handler.dataimport.scheduler.ApplicationListener
</listener-class>
</listener>
在E:\Solr\solr-7.7.2\solr_home目录新建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=dictionary_core
# solr server name or IP address
# [defaults to localhost if empty]
server=localhost
# solr server port
# [defaults to 80 if empty]
# solr的端口
port=8080
# application name/context
# [defaults to current ServletContextListener's context (app) name]
webapp=solr
# URL params [mandatory]
# remainder of URL
# 下面配置的是定时增量扫描,clean = false表示不清楚已有索引
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=/select?qt=/dataimport&command=full-import&clean=true&commit=true
# 重做索引时间间隔的计时开始时间,第一次真正执行的时间=reBuildIndexBeginTime+reBuildIndexInterval*60*1000;
# 两种格式:2012-04-11 01:00:00 或者 01:00:00,后一种会自动补全日期部分为服务启动时的日期
reBuildIndexBeginTime=01:00:00
5.Solr集成SpringBoot
1.修改pom.xml文件,添加jar文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
2.修改application.properties文件,添加指定Solr请求地址:
spring.data.solr.host=http://localhost:8080/solr/
执行查询条件:
package com.example.solr.controller;
import lombok.extern.slf4j.Slf4j;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.MapSolrParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* @Author: swordsman
* @Date: 2019/10/19 10:42
* @Version: 1.0.0
*/
@Slf4j
@RestController
@RequestMapping("/solr")
public class SolrCityController {
@Autowired
private SolrClient solrClient;
@RequestMapping("/query")
public SolrDocumentList query() {
SolrDocumentList list = null;
try {
log.info("进入solr查询操作。");
//查询条件
Map<String, String> param = new HashMap<>(10);
param.put("q", "*:*");
param.put("start", "0");
param.put("rows", "10");
param.put("fq","cityName:*香港*");
//封装参数
MapSolrParams solrParams = new MapSolrParams(param);
//指定查询的连接,并执行结果
QueryResponse response = solrClient.query("dictionary_core", solrParams);
//处理返回的结果
list = response.getResults();
for (SolrDocument doc : list) {
log.info("城市doc:{}", doc);
log.info("城市名称:{}", doc.get("cityName"));
log.info("城市编码:{}", doc.get("cityCode"));
}
}catch (Exception e){
log.error("solr请求出现异常:",e);
}
return list;
}
}
查询返回结果为:
2019-11-17 13:56:50.130 INFO 11720 --- [nio-8001-exec-6] c.e.solr.controller.SolrCityController : 进入solr查询操作。
2019-11-17 13:56:50.147 INFO 11720 --- [nio-8001-exec-6] c.e.solr.controller.SolrCityController : 城市doc:SolrDocument{cityName=中国香港, parentId=0, cityCode=810000, id=3697, _version_=1650424472567545857}
2019-11-17 13:56:50.147 INFO 11720 --- [nio-8001-exec-6] c.e.solr.controller.SolrCityController : 城市名称:中国香港
2019-11-17 13:56:50.147 INFO 11720 --- [nio-8001-exec-6] c.e.solr.controller.SolrCityController : 城市编码:810000
2019-11-17 13:56:50.147 INFO 11720 --- [nio-8001-exec-6] c.e.solr.controller.SolrCityController : 城市doc:SolrDocument{cityName=中国香港岛, parentId=810000, cityCode=810100, id=3698, _version_=1650424473129582594}
2019-11-17 13:56:50.147 INFO 11720 --- [nio-8001-exec-6] c.e.solr.controller.SolrCityController : 城市名称:中国香港岛
2019-11-17 13:56:50.147 INFO 11720 --- [nio-8001-exec-6] c.e.solr.controller.SolrCityController : 城市编码:810100
以上表示查询成功。
6.个人心得与感受
个人使用solr也有一段时间了。在使用的过程中,我感觉Solr像一把巨剑。在感受它“锋利”的同时,我也深深体会到了它的“沉重”。比如:每创建一个Core都要去手动添加data-config配置文件,并指定它的配置路径。还有对于数据库分表的情况,虽然在data-config.xml文件同时支持创建多个映射实体,但是却会存在数据丢失的情况,所以目前的一个解决方案是,一个表对应一个Core。不过话又说回来,Solr作为一个面向企业级的web搜索服务器,能继续保持开源,免费。这就已经很难得。