上一篇: 一文带你了解 KDP 中的全文检索引擎 Apache Solr (上)
5、安装和配置 Solr
5.1 下载 Solr
访问 Solr 的官方网站(https://solr.apache.org/downloads.html)下载最新版本的 Solr。可以选择下载标准发布版或者镜像版本。本文使用的是linux标准发布版本,解压下载的文件到目标文件夹。
!
如图,有3个包:
solr-8.11.2.tgz 适用于 Linux/Unix/OSX 系统
solr-8.11.2.zip 适用于 Microsoft Windows 系统
solr-8.11.2-src.tgz包 Solr 源代码
解压后目录如下:

bin:此目录中包含几个重要的脚本,这些脚本将使使用 Solr 更容易。
▪ solr和 solr.cmd
这是 Solr 的控制脚本,也称为 bin/solr(对于 Linux)或者 bin/solr.cmd(对于 Windows)。这个脚本是启动和停止 Solr的首选工具。也可以在运行 SolrCloud 模式时创建集合或内核、配置身份验证以及配置文件。
▪ post
Post Tool,它提供了用于发布内容到 Solr 的一个简单的命令行界面。
▪ solr.in.sh 和 solr.in.cmd
这些分别是为 Linux 和 Windows 系统提供的属性文件。在这里配置了 Java、Jetty 和 Solr的系统级属性。许多这些设置可以在使用 bin/solr 或者 bin/solr.cmd 时被覆盖,但这允许你在一个地方设置所有的属性。
▪ install_solr_services.sh
该脚本用于Linux 系统以安装 Solr 作为服务
contrib:Solr 的 contrib 目录包含 Solr 专用功能的附加插件。
dist:该 dist 目录包含主要的 Solr.jar 文件。
docs:该 docs 目录包括一个链接到在线 Javadocs 的 Solr。
example:该 example 目录包括演示各种 Solr 功能的几种类型的示例
licenses:该 licenses 目录包括 Solr 使用的第三方库的所有许可证。
server:此目录是 Solr 应用程序的核心所在。此目录中的 README 提供了详细的概述,但以下是一些特点:
▪ Solr 的 Admin UI(server/solr-webapp)
▪ Jetty 库(server/lib)
▪ 日志文件(server/logs)和日志配置(server/resources)
▪ 示例配置(server/solr/configsets)
5.2 启动 Solr
进入 Solr 的解压缩文件夹,使用终端或命令行工具进入 “bin” 子目录,然后执行以下命令启动 Solr:
Bash
bin/solr start
这将启动 Solr 服务,默认监听在端口8983。在浏览器中打开以下URL,并验证我们的Solr实例正在运行。
http://localhost:8983/solr/#/
当Solr服务器在独立模式下启动时,配置称为核心,当在SolrCloud模式下启动时,配置称为集合。在这个例子中,我们采用独立模式部署。
5.3 配置Solr
a.创建 Solr 核心:
Solr 以“核心”(Core)为单位来组织数据索引和配置。要创建一个新核心,使用以下命令:
Bash
bin/solr create -c mycore
这将创建一个名为 “mycore” 的新核心。
b.配置核心:
进入新核心的配置目录,通常位于 “server/solr/mycore/conf”,并编辑 “solrconfig.xml” 和 “schema.xml” 文件,以根据应用程序需求进行配置。您可以定义字段类型、索引策略、查询解析器等。
c.导入数据:
在核心配置好后,您可以使用 Solr 的数据导入工具将数据导入到核心中。数据可以来自各种数据源,如数据库、XML、JSON等。配置数据导入需要编辑 “data-config.xml” 文件。
solr允许用户从数据库中创建索引,便于用户查询。
进入对应core的conf目录下,找到data-config.xml进行配置,例如:
XML
<?xml version="1.0" encoding="utf-8"?>
<dataConfig>
<dataSource name="source2" driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.151.95:3306/demo"
user="root"
password=""
batchSize="-1"/>
<document name="demo">
<entity name="student" pk="id" dataSource="source2" query="select id,stu_no,stu_name,apart_id,stu_sex,stu_card from student">
<field column="id" name="id" />
<field column="stu_no" name="no" />
<field column="stu_name" name="name" />
<field column="apart_id" name="apartId" />
<field column="stu_sex" name="sex" />
<field column="stu_card" name="cardNo" />
</entity>
</document>
</dataConfig>
其中,dataSource配置数据库的一些信息,包括名称、驱动类、url、用户名和密码等。
在document中,需要配置entity、filed等信息,查询语句也在这进行配置。
数据库导入索引的配置文件data-config.xml,为了让Core识别,将如下配置添加到solrconfig.xml文件中,并将data-config.xml放在和solrconfig.xml同级目录下。
XML
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
d.如果修改过配置,需要重启 Solr 进行索引和搜索:
最后,使用以下命令重启 Solr 服务,以开始索引和搜索操作:
Bash
bin/solr stop -all
bin/solr start -p 8983
您可以通过浏览器访问 http://localhost:8983/solr/ 来访问 Solr 的管理界面,以管理核心、查看索引信息和执行查询。
6. 在 Springboot 中整合 Solr
6.1 创建搜索服务接口
SerachService
Java
@Slf4j
@Service
public class SerachServiceImpl implements SerachService {
@Override
public JsonResult searchAllData(JSONObject param , String userid,Integer is_admin) {
JSONObject jb = new JSONObject();
try {
//获取solr返回的json数据
StringBuilder sb;
//自定义json
sb = new StringBuilder(StrUtil.format("/select?q=search_text_s:*{}*", param.getString("search"))+" "+(org.apache.commons.lang3.StringUtils.isBlank(equal)?"":"AND type_s:"+equal)+""+(org.apache.commons.lang3.StringUtils.isBlank(notEqual)?"":"AND -dataType_s:"+notEqual));
String type = param.getJSONArray("condition").toJavaList(Map.class).stream().filter(m -> m.get("pId") != null).map(m -> StrUtil.format("*,{}*", m.get("alias").toString())).collect(Collectors.joining(" or "));
if (StrUtil.isNotBlank(type)) {
sb.append(StrUtil.format("&fq=dataType_s:({})", type));
}
sb.append(StrUtil.format("&start={}&rows={}&wt=json", (param.getInteger("starts")-1)*param.getInteger("rows"), param.getInteger("rows")));
String url = solrUrl + sb;//+执行条件
jb = JSONObject.parseObject(SolrSearchResult.getSolrSearchResult(url));
JSONArray docs = jb.getJSONObject("response").getJSONArray("docs");//获取docs数据
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
//循环标识收藏,添加searchTitle
for (int i = 0; i < docs.size(); i++) {
JSONObject object = docs.getJSONObject(i);
//数据来源
object.put("dataFrom", "数据中心");
if (StrUtil.isNotBlank(param.getString("search"))){
//截取关键字位置前后一段话作为searchTitle
//开头
int indexStart = object.getString("search_text_s").indexOf(param.getString("search"));
//结尾
int indexEnd = indexStart + param.getString("search").length();
if ("UNSTRUCTURED".equals(object.getString("dataType_s"))){
object.put("searchTitle", "文件名称:"+object.getString("id"));
}else {
object.put("searchTitle", object.getString("search_text_s").substring(indexStart < 5 ? 0 : indexStart-5, object.getString("search_text_s").length() - indexEnd > 5 ? (indexEnd + 5) : object.getString("search_text_s").length()));
}
}else {
if ("UNSTRUCTURED".equals(object.getString("dataType_s"))){
object.put("searchTitle", "文件名称:"+object.getString("id"));
}else {
object.put("searchTitle", object.getString("search_text_s"));
}
}
if (is_admin !=null && is_admin==1){
object.put("isAuth", 1);
}else {
//判断门户综合查询是否有权限查询
......
//收藏标识
List<String> maps = dataAdvancedSerachDao.selectAllCollectionSearchTitle(userid);
//默认0
object.put("collect", "0");
if (maps != null && maps.size() > 0 && maps.contains(object.getString("id"))) {
object.put("collect", "1");
}
}
if(StrUtil.isNotBlank(param.getString("search"))){
/*记录查询日志*/
dataAdvancedSerachDao.insertFullTextSearchLog(Snowflake.id(),userid,param.getString("search"),"SEARCH");
}
} catch (Exception e) {
e.printStackTrace();
jb.put("exception", e.getMessage());//捕获异常
}
return JsonResult.data(jb.getJSONObject("response"));
}
}
6.2 创建搜索服务消费者
DataAdvancedSerachController
Java
@ApiOperation(value = "全文检索",notes = "" +
"{\n" +
" \"search\": \"\",\n" +
" \"condition\": \"[]\",\n" +
" \"starts\": 0,\n" +
" \"custom\": true,\n" +
" \"customJson\": {},\n" +
" \"rows\": 10\n" +
"}" +
"",position = 1)
@PostMapping("searchAllData")
public JsonResult searchAllData(@RequestBody JSONObject param){
return serachService .searchAllData(param, getSysUser().getUserid(),getSysUser().getIs_admin());
}
6.3 展示效果





