springboot Solr 史上最详细

Solr全文检索

springboot Solr 史上最详细_第1张图片
全文检索目录.png

一、Solr

官网下载:https://lucene.apache.org/solr/downloads.html

1、下载 .zip 为windows版

我下载的最新版本solr-8.2.0:内嵌jeety服务器,solr5之前的版本都需要放到自己的tomcat里.
下载:solr-8.2.0.zip
安装:
下载完成之后放在的D:\solr-8.2.0目录下,然后解压到当前目录
解压结构目录说明:
​ 还有一个:server文件夹,图示比较老的,没有显示server。

springboot Solr 史上最详细_第2张图片
solr安装目录结构.png

2、启动、关闭solr

在解压之后的solr目录中找到bin文件夹,进去之后右键进入Powershell输入以下命令:

# 启动 
.\solr start

其它命令:

# 启动 
.\solr start
# 关闭 
.\solr stop -all

# 步骤:
# 启动 Solr 将默认监听 8983 端口,其中 -m 1g 指定分配给 JVM 的内存为 1 G
.\solr start -m 1g

# 接下来我们创建一个solr应用:在solr的目录下生成应用对应的文件夹wenda,这个文件夹非常重要,后面我们会在该文件夹下,配置文件来实现中文检索
.\solr create -c wenda

测试启动是否成功:
其中8983是默认端口号。此时在浏览器输入网址http://localhost:8983/solr/#/
成功的话即可看到如下图界面。

springboot Solr 史上最详细_第3张图片
启动成功页面.png

3、创建core文件夹

两种方式效果一样,方式一方便而已。

创建core文件夹方式一(推荐):

cmd在solr-8.2.0/solr/bin目录下(注意,需要在solr start启动solr后才能创建)输入:

.\solr create -c corename    # (core名称,自定义)命令创建一个core

重启:

.\solr stop -all

 启动 
.\solr start

运行完成后在浏览器中访问http://localhost:8983/solr/#/(刷新页面)可以看到如下图所示,新创建的core被添加进去

springboot Solr 史上最详细_第4张图片
创建的corename.png

此时打开文件夹D:\solr-8.2.0\server\solr可以看到下面多了一个corename文件夹,就是我们刚才创建的core。创建core可以直接在文件夹操作,百度上可以收到。这里为了方便使用命令创建。

创建core文件夹方式二:

在solr目录中的\server\solr文件夹中创建一个文件夹,我这边文件夹名称叫做core(名称随便起)。然后把\server\solr\configsets\sample_techproducts_configs下面的conf文件夹复制到刚才创建的core文件夹下面。

完成上面操作之后启动solr,启动成功之后打开浏览器进入地址:http://127.0.0.1:8983/solr/#/

可以看见solr的管理界面,点击左侧的Core Admin,在新页面的name和instanceDir输入框中分别修改为刚才创建的文件夹名称(我这里是core),然后点击下面Add Core按钮即可成功创建core。

创建成功之后,会在你刚才创建的core文件夹下面生成一个文件夹和一个文件.properties,这样即表示创建成功*。

4、创建springboot项目和测试代码

(solr在项目中使用:此处连接的是core,方式二创建的;也可以连接方式一创建的corename)
pom.xml依赖


    org.springframework.boot
    spring-boot-starter-data-solr

具体pom文件内容:


    org.springframework.boot
    spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-test
    test


    org.springframework.boot
    spring-boot-starter-tomcat
    provided




    io.swagger
    swagger-models
    1.5.21
    


    io.swagger
    swagger-annotations
    1.5.21
    


    io.springfox
    springfox-swagger-ui
    2.9.2


    io.springfox
    springfox-swagger2
    2.9.2
    
        
            io.swagger
            swagger-models
        
        
            io.swagger
            swagger-annotations
        
    


.yml文件

server:
  context-path: /
  port: 8080
spring:
  data:
    solr:
      #后面这个core就是文件夹的名称,这里也可以不用写这个,如果这里不指定core,那么在代码中使用的时候,就需要指定core。
      #代码中可以指定core的地方有注释可以看
      host: http://127.0.0.1:8983/solr/core

添加swagger2配置
创建文件夹:config\Swagger2Config.java

package com.dist.config;

import com.google.common.base.Predicate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author yangmin
 * @date 2018/8/15
 * @desc
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket adminApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("Admin API")
                .forCodeGeneration(true)
                .pathMapping("/")
                .select()
                .paths(paths())
                .build()
                .apiInfo(apiInfo())
                .useDefaultResponseMessages(false);
    }

    private Predicate paths(){
        return PathSelectors.regex("^/(?!error).*$");
    }

    private ApiInfo apiInfo(){
        Contact contact = new Contact("BaiDu", "controller://baidu.com", " [email protected]");
        return new ApiInfoBuilder()
                .title("个人SpringBoot测试系统")
                .description("开发API文档")
                .contact(contact)
                .version("1.0")
                .build();
    }
}

在resources/static下创建index.html
把以下内容复制,需要更改端口和项目地址




    
    Title


进入首页

进入swagger页面测试2

controller下SolrController.java类


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * @author [email protected]
 * @data 2019/8/15 15:43
 */
@RequestMapping(value = "rest/solr")
@RestController
@Api(tags = {"SolrController"},description = "Solr 全文检索")
public class SolrController {

    @Autowired
    private SolrClient client;

    @ApiOperation(value = "添加文档内容",notes = "向文档中添加域,必须有id域,域的名称必须在scheme.xml中定义",httpMethod = "GET")
    @RequestMapping(value = "insert",method = RequestMethod.GET)
    public Object validator(@ApiParam(value = "name") @RequestParam String name,
                            @ApiParam(value = "age") @RequestParam String age){
        try {
            String idStr = String.valueOf(System.currentTimeMillis());

            SolrInputDocument document = new SolrInputDocument();
            document.setField("id", idStr);
            document.setField("name", name);
            document.setField("age",age);

            // 把文档对象写入索引库
            client.add("core",document);//如果配置文件中没有指定core,这个方法的第一个参数就需要指定core名称,比如client.add("core", doc);
            client.commit("core");//如果配置文件中没有指定core,这个方法的第一个参数就需要指定core名称client.commit("core");
            return idStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "error";
    }


    @ApiOperation(value = "更新文档内容",notes = "更新文档内容,跟添加的区别是:id不能变,其他的可以变",httpMethod = "GET")
    @RequestMapping(value = "updateDocument",method = RequestMethod.GET)
    public Object updateDocument(@ApiParam(value = "idStr") @RequestParam String idStr,
                               @ApiParam(value = "name") @RequestParam String name,
                               @ApiParam(value = "age") @RequestParam String age) throws Exception{
        // 创建一个文档对象, 向文档中添加域,必须有id域,域的名称必须在scheme.xml中定义
        SolrInputDocument document = new SolrInputDocument();
        document.setField("id", idStr);
        document.setField("name", name);
        document.setField("age",age);
        // 把文档对象写入索引库
        client.add("core",document);
        // 提交
        client.commit("core");
        return document;
    }


    @ApiOperation(value = "全量或增量更新-数据库-没成功",notes = "java操作Solr的全量或增量更新,可以结合定时任务做定时全量或增量更新",httpMethod = "PUT")
    @RequestMapping(value = "updateSolrData",method = RequestMethod.PUT)
    public void updateSolrData() throws SolrServerException, IOException {
        //创建一个查询对象
        SolrQuery solrQuery = new SolrQuery();

        //增量更新全部完成;注意这里entity的值为solr-data-config.xml里entity标签里的name值
        final String SOLR_DELTA_PARAM = "/dataimport?command=delta-import&entity=order_info&clean=false&commit=true";
        //全量更新全部完成
        final String SOLR_FULL_PARAM = "/dataimport?command=full-import&entity=order_info&clean=true&commit=true";
        //设置更新方式
        solrQuery.setRequestHandler(SOLR_DELTA_PARAM);

        // 执行查询
        QueryResponse query = client.query("core",solrQuery);

        //提交
        client.commit("core");

    }

    @ApiOperation(value = "查询文档内容",notes = "查询文档内容",httpMethod = "GET")
    @RequestMapping(value = "queryDocument",method = RequestMethod.GET)
    public Object queryDocument(@ApiParam(value = "条件",defaultValue = "*:*") @RequestParam String condition,
                              @ApiParam(value = "连接文件夹 默 core",defaultValue = "core") @RequestParam String collection,
                              @ApiParam(value = "分页起始 默 1",defaultValue = "1") @RequestParam Integer pageStart,
                              @ApiParam(value = "分页结束 默 10",defaultValue = "10") @RequestParam Integer pageEnd) throws Exception {
        // 创建一个查询条件
        SolrQuery solrQuery = new SolrQuery();
        // 设置查询条件
        solrQuery.setQuery(condition);
        // 设置分页
        solrQuery.setStart(pageStart);
        solrQuery.setRows(pageEnd);
        // 执行查询
        QueryResponse query = client.query(collection,solrQuery);
        // 取查询结果
        SolrDocumentList solrDocumentList = query.getResults();

        System.out.println("总记录数:" + solrDocumentList.getNumFound());

        for (SolrDocument sd : solrDocumentList) {
            System.out.println(sd.get("id"));
            System.out.println(sd.get("name"));
            System.out.println(sd.get("age"));
        }
        return solrDocumentList;
    }


    @ApiOperation(value = "删除文档",notes = "删除文档",httpMethod = "DELETE")
    @RequestMapping(value = "deteleDocument",method = RequestMethod.DELETE)
    public Object deteleDocument(@ApiParam(value = "连接文件夹 默 core" ,defaultValue = "core") @RequestParam String collection,
                               @ApiParam(value = "idStr") @RequestParam String idStr) throws Exception {
        // 根据id删除
        UpdateResponse response = client.deleteById(collection, idStr);
        // 根据条件删除
        // httpSolrServer.deleteByQuery("");
        // 提交
        client.commit(collection);

        return response;
    }

}

然后启动该项目之后,进入http://localhost:8080/swagger-ui.html地址即可测试插入索引操作。插入成功之后,在solr管理界面的左下方有一个下拉框,选择你创建的core之后,再选择Query,往下拖到最后,点击Execute Query即可看见你刚才插入的索引。

其他问题:

刚才我们代码中插入了两个列(id、name),如果你想新增一个列,比如名称叫做age,然后启动项目,在插入索引,在solr管理平台中就看不见这个列名和列对应的值,原因是id、name这两列在solr中已经默认配置了。这种情况解决方式如下:

在你创建的core文件夹下面,打开conf文件夹,修改里面的managed-schema文件,修改地点如下:

132行后面增加(后面这几行随意位置增加就可以)


245行后面增加(后面这几行随意位置增加就可以)

修改完成之后重启solr,然后重新插入索引就可以成功操作了。
再测试:
SolrController.java

SolrInputDocument doc = new SolrInputDocument();
            doc.setField("id", idStr);  //id是默认配置,在你创建的core文件夹下面,打开conf文件夹,修改里面的managed-schema文件
            doc.setField("name", content); // name是默认配置
            doc.setField("age","23"); //自定义配置:在你创建的core文件夹下面,打开conf文件夹,修改里面的managed-schema文件,添加列 age

效果图:


springboot Solr 史上最详细_第5张图片
solr效果.png

5.solr连接数据库

此处测试配置的是oracle数据库,用的是方式一创建的corename文件包

1、添加驱动依赖包

添加驱动依赖包到如下目录:D:\solr-8.2.0\server\solr-webapp\webapp\WEB-INF\lib,我使用的oracle数据库,添加的是oracle驱动包,其他数据库添加相应驱动包ojdbc6.jar即可.
ojdbc6.jar下载地址:百度网盘
链接:https://pan.baidu.com/s/1OlNdA32xKGXUTbFzDTLSZQ 提取码:bgul
我添加的是ojdbc6.jar ,也可以添加其它版本如:ojdbc8.jar 或者是mysql的驱动jar等

2、配置dataimporthandler相关包

找到解压目录D:\solr-8.2.0\dist下的solr-dataimporthandler-8.2.0.jar包和solr-dataimporthandler-extras-8.2.0.jar两个包,也复制到D:\solr-8.2.0\server\solr-webapp\webapp\WEB-INF\lib目录下

3、添加数据库配置

找到目录D:\solr-8.2.0\server\solr\corename\conf下的solrconfig.xml并添加配置

    
     
          
              data-config2.xml  
          
     
4、创建data-config2.xml数据库连接配置

在目录D:\solr-8.2.0\server\solr\corename\conf下新建一个文件data-config2.xml并添加如下内容:



     
    
        
             
             
             
        
    

其中数据库驱动,地址,表,用户名,密码和查询sql及字段都需要替换成你自己数据库的相应配置。field的culumn是数据库字段名称(查询出来后没有改别名下),name可以自定义,之后就是solr字段名称。

5、配置managed-schema

打开文件D:\solr-8.2.0\server\solr\corename\conf下的managed-schema,并在其中的标签里面添加如下配置:

   
   
   
   

注意上面的name需要和前面userEntity配置的字段一样如:

6、验证是否成功

关掉之前打开的solr,重新启动。

cmd到D:\solr-8.2.0\bin目录下输入命令:

.\solr stop -all

.\solr start

待启动成功后,浏览器打开solr地址:

http://localhost:8983/solr/#/

  • 导入库中数据

并按如下图选择好,其中的userEntity是你的表名。点击excute执行

springboot Solr 史上最详细_第6张图片
将查询库中的数据导入solr.png

导入完成后/或刷新页面。

  • 查询导入的所有数据:
springboot Solr 史上最详细_第7张图片
查询效果.png

数据库连接配置完成!

6.solr 安装中文分词器

第一步:下载Ikanalyzer7.x分词器的jar 文件,下载地址:https://search.maven.org/search?q=com.github.magese

springboot Solr 史上最详细_第8张图片
ik-analyzer-solr7.png

第二步:将下载的Ikanalyzer7.x.jar 文件拷贝至D:\solr-8.2.0\server\solr-webapp\webapp\WEB-INF\lib


springboot Solr 史上最详细_第9张图片
ik-analyzer-solr7位置.png

第三步:在solrHome(solr数据源)文件夹,新建一个mycore文件夹,D:\solr-8.2.0\server\solr


springboot Solr 史上最详细_第10张图片
新建 mycore.png

第四步:把solr-8.1.0安装包中的example→example-DIH→solr→solr下的所有文件拷贝到solrHome(solr数据源)文件夹下的mycore文件夹中。


springboot Solr 史上最详细_第11张图片
复制配置mycore.png

data是之后运行才会出来的,不用在意;


springboot Solr 史上最详细_第12张图片
复制配置mycore2.png

第五步:打开solrHome(solr数据源)文件夹中的mycore→conf→managed-schema文件,添加如下代码:

    
    
      
          
          
      
      
          
          
      
    

第六步:重启solr ,输入:http://localhost:8983/solr/#/

springboot Solr 史上最详细_第13张图片
分词器效果.png

7.Solr 界面功能

springboot Solr 史上最详细_第14张图片
Solr界面功能1.png

springboot Solr 史上最详细_第15张图片
Solr界面功能2.png
springboot Solr 史上最详细_第16张图片
Solr界面功能3.png
springboot Solr 史上最详细_第17张图片
Solr界面功能4.png
springboot Solr 史上最详细_第18张图片
Solr界面功能5.png

8.Solr全量更新/增量更新 -要配置数据库

1、全量更新

参考 5.solr连接数据库 配置,完成后:


springboot Solr 史上最详细_第19张图片
solr全量更新.png

记住:clean=true、commit=true

2、增量更新

1.首先要弄懂几个必要的属性,以及数据库建表事项,和dataimporter.properties 、data-config.xml里面的数据

  
  
      注意这个只能返回ID字段
  
   注意这个只能返回ID字段
  

2.数据库配置注意事项

1.如果只涉及添加,与修改业务,那么数据库里只需额外有一个timpstamp字段
就可以了,默认值为当前系统时间,CURRENT_TIMESTAMP
2.如果还涉及删除业务,那么数据里就需额外再多添加一个字段isdelete,int类型的
用0,1来标识,此条记录是否被删除

3.dataimporter.properties

这个配置文件很重要,它是用来记录当前时间与上一次修改时间的,通过它能够找出,那些,新添加的,修改的,或删除的记录标识,此条记录是否被删除的记录

4.增量更新就是在全量更新的基础上加上一些配置,data-config.xml配置如下:

原配置:



     
    
        
            
             
             
             
        
    

增量更新配置:



     
    
        
             
             
             
             
        
    

5.通过后台管理手动增量更新和通过浏览器手动更新

springboot Solr 史上最详细_第20张图片
solr增量更新.png

在浏览器直接输入网站 :

http://127.0.0.1:8983/solr/#/corename/dataimport//dataimport

记住:clean=false、commit=true

9、solr 常见的自动更新方式

方式一:solr 自带的增量更新更新

**1.下载jar包 **

apache-solr-dataimportscheduler.jar、solr-dataimporthandler-7.0.0.jar、solr-dataimporthandler-extras-7.0.0.jar到 solr 项目的\WEB-INF\lib 目录下

apache-solr-dataimportscheduler 的下载地址:

链接:https://pan.baidu.com/s/110-F7DrO_4QEILWb6FFvzQ
提取码:yxm8

2. 修改web.xml文件配置监听,在servlet节点前增加:

   
          
                org.apache.solr.handler.dataimport.scheduler.ApplicationListener
          
    

3.创建 dataimport.properties

在solrHome(存储solr数据的目录) 的目录下创建conf文件夹,创建 dataimport.properties 文件,内容根据实际情况修改,内容如下:

#################################################
#                                              #
#      dataimport scheduler properties        #
#                                              #
#################################################
 
#  tosync or not to sync
#  1- active; anything else - inactive
# 这里的配置不用修改
syncEnabled=1
 
# which cores to schedule
#  ina multi-core environment you can decide which cores you want syncronized
# leave empty or comment it out if using single-core deployment
#  修改成你所使用的core,我这里是我自定义的core:simple
syncCores=active
 
# solr server name or IP address
# [defaults to localhost if empty]
这个一般都是localhost不会变
server=localhost
 
# solr server port
# [defaults to 80 if empty]
#  安装solr的tomcat端口,如果你使用的是默认的端口,就不用改了,否则改成自己的端口就好了
port=8089
 
# application name/context
# [defaults to current ServletContextListener's context (app) name]
#  这里默认不改
webapp=solr
 
# URL params [mandatory]
# remainder of URL
#  这里改成下面的形式,solr同步数据时请求的链接
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 03:10:00 或者 03:10:00,后一种会自动补全日期部分为服务启动时的日期
reBuildIndexBeginTime=03:10:00

最后重启solr,在数据库中添加一条数据,静等一分钟,然后query。因为我们设置的是一分钟监听一次

方式二:使用windows 的计划任务进行增量更新

此方法,用于tomcat下部署的solr。

1.在windows开始那里搜索“计划任务”

springboot Solr 史上最详细_第21张图片
solr计划任务1.jpg

2.创建一个新的计划任务

springboot Solr 史上最详细_第22张图片
solr计划任务2.jpg

3.对计划任务的常规、触发器、操作 进行设置

springboot Solr 史上最详细_第23张图片
solr计划任务3.jpg

springboot Solr 史上最详细_第24张图片
solr计划任务4.jpg

springboot Solr 史上最详细_第25张图片
solr计划任务5.jpg

4.启动计划任务

5.solr.bat 中的内容为(使用curl进行模拟请求,curl 需要下载):

curl http://localhost:8089/solr/active/dataimport?command=delta-import^&clean=false^&commit=true

6.windows 的curl 需要下载配置环境变量(和jdk的差不多),curl下载地址为:

链接:https://pan.baidu.com/s/1CArPu0vdPGGWRfo8KuZxWg 提取码:09ks (64位系统的,32位的可以去官网下载)

方式三:linux下使用 crontab实现增量更新

此方法,用于tomcat下部署的solr。

1.修改crontab的配置文件:vim /etc/crontab

crontab -e
*/5 * * * * curl http://localhost:8089/solr/active/dataimport?command=delta-import^&clean=false^&commit=true

注:5分钟执行一次增量索引(可根据实际业务调整时间)

你可能感兴趣的:(springboot Solr 史上最详细)