Solr7.7.3的部署及使用:
一、环境准备:
由于工作需要使用solr,并且以前也没有用到过,于是各种百度,看了好多大神的博客,在碰了一次次壁之后终于有一些心得,于是记录一下过程,也给遇到类似问题的小伙伴提供一些参考,希望对各位有用。
我的环境是:
系统:CentOS 7+
jdk版本:jdk1.8以上
solr版本:Solr7.7.3
tomcat版本:tomcat 8
solr下载地址:http://archive.apache.org/dist/lucene/solr/7.7.3/
所需的资源已上传网盘:
链接: https://pan.baidu.com/s/1E30ixIScqG_x85UATi7-yA
提取码: ysd6
二、jdk环境的安装
# 切换到 root 用户:
su ‐ root
# 创建 JDK 安装目录:
mkdir /usr/local/java
tar -zxvf /usr/local/java/jdk-8u261-linux-x64.tar.gz
rm -rf jdk-8u261-linux-x64.tar.gz
# 将 JDK‐Linux 压缩包上传到/usr/local/java 目录后,解压缩,推荐做软链接
ln -s /usr/local/java/jdk1.8.0_261/ /usr/local/java/jdk
# 添加环境变量:
echo 'export JAVA_HOME=/usr/local/java/jdk' >> /etc/profile
echo 'export JRE_HOME=${JAVA_HOME}/jre' >> /etc/profile
echo 'export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib' >> /etc/profile
echo 'export PATH=${JAVA_HOME}/bin:$PATH' >> /etc/profile
source /etc/profile
# 验证环境是否安装好:
#若出现 java version "1.8.0_261" 即代表 jdk 环境安装成功
java -version
三、关闭防火墙
如果要远程连接的 linux 的话,要记得关闭防火墙:
# 关闭防火墙:
systemctl stop firewalld.service
# 关闭 SeLinux:
临时关闭:setenforce 0
永久关闭:vi /etc/selinux/config SELINUX=enforcing 改为 SELINUX=disabled
四、创建 solr 用户
使用 root 创建 solr 用户,将 solr 和 tomcat 压缩包传入,并解压:
# 创建 solr 用户并修改密码(建议密码也设置成 solr)
useradd solr
passwd solr
# (之后连续输入两次 solr 用户的密码即可创建 solr 用户)
# 切换 solr 用户:
su - solr
# 使用 ftp 工具将 solr-7.7.3.zip 和 apache-tomcat-8.5.57.tar.gz 传入用户根目录下,并解压
tar -zxvf apache-tomcat-8.5.57.tar.gz
unzip solr-7.7.3.zip
# 修改 tomcat 名为apache-tomcat-solr
mv apache-tomcat-8.5.57 apache-tomcat-solr
五、部署 solr
# 启动 tomcat,看是否能成功启动(可忽略):
sh /home/solr/apache-tomcat-solr/bin/startup.sh
curl http://localhost:8080
# 如果有页面返回,则说明 tomcat 启动成功,然后关闭 tomcat
sh /home/solr/apache-tomcat-solr/bin/shutdown.sh
# 进入 apache-tomcat-solr 目录下,删除 webapp 下所有的文件:
cd apache-tomcat-solr/webapps/
rm -rf *
# 复制 solr-7.7.3\server\solr-webapp 目录下的 webapp 到 Tomcat8.5.5\webapps 目录下,然后改名为 solr:
cp -r /home/solr/solr-7.7.3/server/solr-webapp/webapp/ /home/solr/apache-tomcat-solr/webapps/
mv /home/solr/apache-tomcat-solr/webapps/webapp/ /home/solr/apache-tomcat-solr/webapps/solr
# 把所需的 jar 包拷贝到:/home/solr/apache-tomcat-solr/webapps/solr/WEB-INF/lib 目录下
# 把所需资源的 classes 文件夹拷贝到:/home/solr/apache-tomcat-solr/webapps/solr/WEB-INF/
# 把 web.xml 拷贝替换到:/home/solr/apache-tomcat-solr/webapps/solr/WEB-INF/
# 把 solr-home 拷贝到 solr 根目录下
# 启动 tomcat ,看 solr 是否能成功打开页面
sh /home/solr/apache-tomcat-solr/bin/startup.sh
# 在浏览器访问页面:http://ip:8080/solr/index.html#/ ,若能成功打开,说明 solr 已经部署完毕.
六、修改配置文件
1. 创建collection
solr主页的地址为:http://ip:port/solr/index.html#/
接下来要创建 solr 的 collection(索引集),一个 collection 相当于一张表,里边存放着索引数
据,如果想要把数据库表的数据同步到 collection 里,需要配置一些文件
比如说我有一张表t_solr_test,我想要把这张表的数据导入到solr里,表结构如图:
需要做如下操作:
# 在solr-home目录下创建一个文件夹(文件夹名和collection名需一致,建议和表名也一致)
mkdir -p /home/solr/solr-home/t_solr_test
cp -r /home/solr/solr-home/configsets/_default/conf/ /home/solr/solr-home/t_solr_test/
执行完以上命令后,在网页端:
2. 添加中文分词器
没有添加中文分词器的时候如图所示:
如何添加分词器呢?
a) 导入jar包: 所需的jar包我已经在第五步的部署solr中已经导入过了
b) 修改/home/solr/solr-home/t_solr_test/conf目录下的managed-schema文件
vi /home/solr/solr-home/t_solr_test/conf/managed-schema
在图中位置加上如下内容:
<!-- 定义ik分词器 -->
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
<!-- 使用IK分词器 -->
<field name="title_ik" type="text_ik" indexed="true" stored="true" />
<field name="content_ik" type="text_ik" indexed="true" stored="false" multiValued="true"/>
重启tomcat,再次输入文本,点击分析,结果如图所示:
说明我们已经使用了中文分词器了。
3.导入数据库数据
那么该如何导入数据库数据呢?
a) 导入jar包: 所需jar到也已经在第五步的部署solr里搞定了
b) 修改配置文件:
vi /home/solr/solr-home/t_solr_test/conf/solrconfig.xml
在如图位置加上以下内容:
<!-- 配置批量数据导入的处理器配置 -->
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
在solrconfig.xml同级目录下新建data-config.xml(名字与上面添加的<str name=“config”>data-config.xml</str>相同)
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<!-- 1.数据库资源,user、password为自己的用户名和密码 -->
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/solr"
user="root" password="123" encoding="UTF-8"/>
<!-- 2.添加到solr的文档信息,根据自己的数据库表取写 -->
<document>
<entity name="t_solr_test" query="SELECT id,name,value FROM t_solr_test" pk="id">
<field column="id" name="id"/>
<field column="name" name="name"/>
<field column="value" name="value"/>
</entity>
</document>
</dataConfig>
再修改managed-schema文件,添加如下内容:
<!-- t_solr_test -->
<field name="name" type="text_ik" indexed="true" stored="true"/>
<field name="value" type="text_ik" indexed="true" stored="true" multiValued="true"/>
注: type=“text_ik” 意思是使用分词器建立索引,我们搜索时也可以通过分词器查询。
重启tomcat,打开如下页面:
点击完Execute按钮后,会出现:
在查询页面点击查询:
可以看到,我们的数据库数据已经同步到了solr索引集里了。
现在,来实验一下我们的中文分词器好用不:
在数据库新增几条数据:
然后同步一下索引集:
搜索中国,就能出现包含中国的两条数据:
七、SpringBoot中整合solr
1.搭建maven工程
pom文件中添加如下依赖:
<!-- SpringBoot整合solr依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
修改application.properties配置文件:
其中spirng.data.solr.host为solr的主机url,一般情况下只用根据自己的情况修改ip和port即可。
2.code的编写
新建一个名叫SolrService的类
/**
* @author zhang_hr
* @date 2021/1/19 15:11
* @description solr服务类
**/
@Service
@Slf4j
public class SolrService {
@Autowired
private SolrClient client;
@Value("${spring.data.solr.host}")
private String solrHost;
/**
* 触发同步数据库 - 表名和collection名需要相同
*
* @param tableName 需要同步的表名
* @param cleanOldData 是否需要清除原collection的全部索引
* @param fullImport 是否全量导入
*/
public void syncTrigger(String tableName, boolean cleanOldData, boolean fullImport) {
// 是否清理原索引信息
String clean = "";
if (cleanOldData) {
clean = "&clean=true";
} else {
clean = "&clean=false";
}
// 是否全量导入
String command = "";
if (fullImport) {
command = "?command=full-import";
} else {
command = "?command=delta-import";
}
String url = solrHost + "/" + tableName + "/dataimport" + command + clean +
"commit=true&optimize=true&wt=json&indent=true";
// solr同步通过http协议调起
try {
HttpUtil.get(url);
log.info("solr同步数据库:[{}]成功!", tableName);
} catch (RuntimeException e) {
throw new RuntimeException("solr failed to synchronize database");
}
}
/**
* 通过id删除指定collection的索引
*
* @param collection 索引集
* @param id 索引id
*/
public void deleteById(String collection, String id) {
try {
client.deleteById(collection, id);
client.commit(collection);
log.info("删除collection:[{}]中id为:[{}]的索引", collection, id);
} catch (Exception e) {
throw new IllegalArgumentException("delete index:" + id + " failure");
}
}
/**
* 清空索引集
*
* @param collection 索引集
*/
public void deleteAll(String collection) {
try {
client.deleteByQuery(collection, "*:*");
client.commit(collection);
log.info("删除collection:[{}]中所有索引", collection);
} catch (Exception e) {
throw new IllegalArgumentException("delete index failure");
}
}
/**
* 根据条件进行删除
*
* @param collection 索引集
* @param condition 条件
*/
public void deleteByCondition(String collection, String condition) {
try {
client.deleteByQuery(collection, condition);
client.commit(collection);
} catch (Exception e) {
throw new IllegalArgumentException("delete index failure");
}
}
/**
* 根据条件进行查询
*
* @param collection 索引集
* @param condition 查询条件
* @param field 查询字段
* @param filter 过滤条件(格式- 字段:条件)
* @return 查询到的结果
*/
public JSONArray queryByCondition(String collection, String condition, String field, String filter) throws IOException, SolrServerException {
JSONArray jsonArray = new JSONArray();
SolrQuery params = new SolrQuery();
// 查询条件
params.set("q", condition);
// 过滤条件
params.set("fq", filter);
// 排序
params.addSort(field, SolrQuery.ORDER.asc);
// 分页
params.setStart(0);
params.setRows(20);
// 默认域
params.set("df", field);
QueryResponse queryResponse = client.query(collection, params);
SolrDocumentList results = queryResponse.getResults();
// 查询到的结果数量
long numFound = results.getNumFound();
for (SolrDocument result : results) {
JSONObject json = new JSONObject(result);
jsonArray.add(json);
}
JSONObject count = new JSONObject();
count.put("totalNum", numFound);
jsonArray.add(0, count);
return jsonArray;
}
}