暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

一文带你了解 KDP 中的全文检索引擎 Apache Solr (下)

原创 KaiwuDB 2024-03-13
232

上一篇: 一文带你了解 KDP 中的全文检索引擎 Apache Solr (上)

5、安装和配置 Solr

5.1 下载 Solr

访问 Solr 的官方网站(https://solr.apache.org/downloads.html)下载最新版本的 Solr。可以选择下载标准发布版或者镜像版本。本文使用的是linux标准发布版本,解压下载的文件到目标文件夹。

image.png!

如图,有3个包:
solr-8.11.2.tgz 适用于 Linux/Unix/OSX 系统
solr-8.11.2.zip 适用于 Microsoft Windows 系统
solr-8.11.2-src.tgz包 Solr 源代码

解压后目录如下:
image.png

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 展示效果

image.png

最后修改时间:2024-03-13 16:04:49
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论