第一、Solr7 简介和环境搭建

1.1  Solr 简介

solr是企业级应用的全文检索项目,它是基于Apache Lucence搜索引擎开发出来的用于搜索的应用工程

运行环境:solr需要java8环境,且需要在环境变量中添加 JAVA_HOME变量。

1.2 Solr7 安装

下载地址 https://lucene.apache.org/solr/mirrors-solr-latest-redir.html  (我下载的是7.4版本的)

   在solr5以前solr的启动都有tomcat作为容器,但是从solr5以后solr内部集成jetty服务器,可以通过bin目录中脚本直接启动。就是从solr5以后跟solr4最大的区别是被发布成一个独立的应用。

  在solr5之后solr其实特别容易安装,有安装包,之后在解压,直接启动bin下solr,solr就这样完成的启动了。。

solr容器 solr7_xml

在bin目录下,执行如下命令 solr start 

solr容器 solr7_tomcat_02

运行成功后显示出端口号(中间可能会报lo4j的错误可以不用管它 不碍事)

solr容器 solr7_solr容器_03

启动后直接访问  http://localhost:8983/solr/#/

solr容器 solr7_xml_04

 1.3 Solr7 常用命令

solr start –p 端口号 单机版启动solr服务

solr restart –p 端口号 重启solr服务

solr stop –p 端口号关闭solr服务

1.4 Solr7 创建core 

1.4.1 core 简介

         简单说core就是solr的一个实例,一个solr服务下可以有多个core,每个core下都有自己的索引库和与之相应的配置文件,所以在操作solr创建索引之前要创建一个core,因为索引都存在core下面。

1.4.2 core 创建方式

第一种: 在bin目录下执行solr create –c name,创建一个core,默认创建出来的位置如下图

solr容器 solr7_tomcat_05

solr容器 solr7_tomcat_06

第二种方式是直接使用AdminUI页面创建一个core,如下图

点击admin core 选择AddCore,添加核心

solr容器 solr7_solr容器_07

name:自定义的名字,建议和instanceDir保持一致
instanceDir: solrhome目录下的实例类目
dataDir:默认填data即可
config:指定配置文件,new_core/conf/solrconfig.xml
schema:指定schema.xml文件,new_core/conf/schema文件(实际上是managed-schema文件)

点击 Add Core

solr容器 solr7_xml_08

这里看到上面提示 无法找打solrconfig.xml文件。这里注意下:创建的instanceDir和dataDir 需存在,就是我们需在solr-7.4.0\server\solr 目录下先去创建目录

solr容器 solr7_solr容器_09

此目录下的conf文件我们可从server\solr\configsets\sample_techproducts_configs中复制

solr容器 solr7_tomcat_10

当创建与复制好后,我们在再页面上创建core  创建成功

创建成功后product目录下会生成你的core和一个properties文件

solr容器 solr7_tomcat_11

第二、Solr7 分词

2.1 什么是分词:

       1.分词是指将一个中文词语拆成若干个词,提供搜索引擎进行查找,比如说:北京大学 是一个词那么进行拆分可以得到:北京与大学,甚至北京大学整个词也是一个语义

  2.市面上常见的分词工具有 IKAnalyzer MMSeg4j  Paoding等,这几个分词器各有优劣,大家可以自行研究。

       IK分词器下载地址:https://github.com/blueshen/ik-analyzer

2.2 Solr7 集成IK分词器

1、下载IK源码并进行源码编译,源码编译执行如下指令(mvn clean install -Dmaven.test.skip=true)

2、把ik-analyzer-8.4.0.jar复制到E:\solr\solr-7.4.0\server\solr-webapp\webapp\WEB-INF\lib中

solr容器 solr7_tomcat_12

3、然后在E:\solr\solr-7.4.0\server\solr-webapp\webapp\WEB-INF目录下新建一个classes目录,把下面三个文件复制进去

solr容器 solr7_solr容器_13

进入之前创建的solr 实例(good)  在E:\solr\solr-7.4.0\server\solr\good\conf下打开managed-schema.xml 添加如下代码:

<!--IK 分词器 -->
	<fieldType name="text_ik" class="solr.TextField">  
        <analyzer type="index" useSmart="false"
            class="org.wltea.analyzer.lucene.IKAnalyzer" />
        <analyzer type="query" useSmart="true"
            class="org.wltea.analyzer.lucene.IKAnalyzer" />
	</fieldType>

2.3 Solr7 集成IK分词器 功能验证

1、打开solr服务,打开你所创建的solr实例(good)

solr容器 solr7_xml_14

 2、选择Analysis  输入要搜索的中文 选择FieldType为text_ik  可以发现分词成功

solr容器 solr7_solr_15

 第三、Solr7 + MySQL8 数据导入

3.1 jar包准备

1、准备mysql连接驱动包,mysql-connector-java-8.0.15.jar

2、找到solr-dataimporthandler-7.4.0.jar和solr-dataimporthandler-extras-7.4.0.jar。这2个jar在solr安装目录下有E:\solr\solr-7.4.0\dist

3、把这3个jar包复制到E:\solr\solr-7.4.0\server\solr-webapp\webapp\WEB-INF\lib 目录下,这其实是一个标准的web项目目录。

solr容器 solr7_xml_16

solr容器 solr7_xml_17

3.2 配置文件准备

1、在solr实例之good(E:\solr\solr-7.4.0\server\solr\good\conf)下新建data_config.xml并编写代码:

<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
    <dataSource  driver="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/myblog?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" user="root" password="123456" />
    <document>
        <entity name="article" query="select * from blog_article" deltaQuery="select * from blog_article" pk="id">
            <field column="id" name="id" />
			<field column="title" name="title" />
			<field column="content" name="content" />
            <field column="pub_time" name="pubTime" />
            <field column="author_id" name="authorId" />
			<field column="category_id" name="categoryId" />
        </entity>
    </document>
</dataConfig>

2、在E:\solr\solr-7.4.0\server\solr\good\conf下的managed-schema文件中,添加如下代码:

<field name="title" type="string" indexed="true" stored="true"/>
<field name="content" type="string" indexed="true" stored="true"/>
<field name="pubTime" type="pdate" indexed="true" stored="true"/>
<field name="authorId" type="pint" indexed="true" stored="true"/>
<field name="categoryId" type="pint" indexed="true" stored="true"/>

3、在E:\solr\solr-7.4.0\server\solr\good\conf下的solrconfig.xml文件中,查询到requestHandler标签的位置,如图:

solr容器 solr7_tomcat_18

4、在requestHandler标签前面加上如下代码:

<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
	<lst name="defaults">
		<str name="config">data_config.xml</str>
	</lst>
  </requestHandler>

5、重新启动solr;

6、在浏览器打开solr,在DataImport中执行导入,左侧绿色字体为导入状态(可点击Refesh Status按钮刷新),如图:

solr容器 solr7_solr容器_19

7、在Query中查看导入结果,如图: 

solr容器 solr7_solr容器_20

第四、Solr7 增量索引

1、将apache-solr-dataimportscheduler-1.4.Jar这个jar包放到E:\solr\solr-7.4.0\server\solr-webapp\webapp\WEB-INF\lib下

2、修改web配置,访问E:\solr\solr-7.4.0\server\solr-webapp\webappWEB-INF文件夹,并打开web.xml文件,增加监听器配置

<!-- 增量索引监听器-->
  <listener>
	 <listener-class>
	    org.apache.solr.handler.dataimport.scheduler.ApplicationListener
	 </listener-class>
   </listener>

3、增加dataimport.properties配置

在这里大家一定要注意目录结构不要放错了位置;

E:\solr\solr-7.4.0\server\solr目录下新建一个conf文件夹

然后在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=good
 
#  solr server name or IP address
#  [defaults to localhost if empty]
server=localhost
 
#  solr server port
#  [defaults to 80 if empty]
#  安装solr的端口
port=8983
 
#  application name/context
#  [defaults to current ServletContextListener's context (app) name]
webapp=solr
 
#  URL params [mandatory]
#  remainder of URL
#  这里改成下面的形式,solr同步数据时请求的链接
params=/dataimport?command=full-import&clean=false&commit=true
 
#  schedule interval
#  number of minutes between two runs
#  [defaults to 30 if empty]
#这里是设置定时任务的,单位是分钟,也就是多长时间你检测一次数据同步,根据项目需求修改
#  开始测试的时候为了方便看到效果,时间可以设置短一点
interval=3
 
#  重做索引的时间间隔,单位分钟,默认7200,即5天; 
#  为空,为0,或者注释掉:表示永不重做索引
reBuildIndexInterval=5
 
#  重做索引的参数
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

4、修改solr 实例good 的数据配置文件data_config.xml 文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
    <dataSource  driver="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/myblog?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" user="root" password="123456" />
    <document>
         <!--  query="select * from blog_article"   query查询是指
               查询出表里所有的符合条件的数据 -->
        <!--
               deltaQuery="select * from blog_article where pub_time > '${dataimporter.last_index_time}'"
               deltaQuery的意思是,查询出所有经过修改的记录的ID
               可能是修改操作,添加操作,删除操作产生的
               (此查询只对增量导入起作用,而且只能返回ID值)
               -->
       <!--
                deltaImportQuery="select * from blog_article where id='${dataimporter.delta.id}'"
                次查询是获取以上两步的ID,然后把其全部数据获取,根据获取的数据
                对索引库进行更新操作,可能是删除,添加,修改
                (此查询只对增量导入起作用,可以返回多个字段的值,一般情况下,都是返回所有字段的列)
-->
        <entity name="article" query="select * from blog_article"
		 deltaImportQuery="select * from blog_article where id='${dataimporter.delta.id}'"
			deltaQuery="select * from blog_article where pub_time > '${dataimporter.last_index_time}'"
		 pk="id">
            <field column="id" name="id" />
			<field column="title" name="title" />
			<field column="content" name="content" />
            <field column="pub_time" name="pubTime" />
            <field column="author_id" name="authorId" />
			<field column="category_id" name="categoryId" />
        </entity>
    </document>
</dataConfig>

${dataimporter.delta.id}指的就是主键如果主键不为id的话就写成你最开始配置的那个<uniqueKey>id</uniqueKey>的值

${dataimporter.last_index_time}  固定写法,更新的判断条件,上一次的修改时间需要大于上一次索引的更新时间

这个参数会自动更新在E:\solr\solr-7.4.0\server\solr\good\conf 下的dataimport.properties文件中,文件内容如下:

solr容器 solr7_tomcat_21

5、solr 服务,重新启动

6、 数据库修改添加一条“西游记”记录, 然后等待一分钟再查询

solr容器 solr7_solr_22

 第四、Tomcat8 集成Solr7

将solr作为一个单独的项目发布到 Tomcat 可没有我们普通的项目发布到 Tomcat 那么简单,从5.0.0版本开始,solr就不提供可供直接发布的war包,所以从5.0.0版本开始,solr发布到 tomcat 的步骤几乎一样,要操作的步骤有以下几步:

1、将E:\solr\solr-7.4.0\server\solr-webapp下的webapp复制到E:\tomcat\webapps/下并且重命名(可以随意命名),这里命名为solr。

solr容器 solr7_tomcat_23

2、复制E:\solr\solr-7.4.0\server\lib\ext下的所有jar,到E:\tomcat\webapps\solr\WEB-INF\lib下。(没错,这个就是那个重命名solr下的WEB-INF/lib)

3、复制E:\solr\solr-7.4.0\server\lib\下metrics相关的jar,到E:\tomcat\webapps\solr\WEB-INF\lib下。

solr容器 solr7_tomcat_24

4、复制E:\solr\solr-7.4.0\server\resources下的log4j.properties文件,到E:\tomcat\webapps\solr\WEB-INF/下的classes文件夹中。(classes文件夹如果没有需要自己创建,这是日志文件)

5、创建solrhome:复制E:\solr\solr-7.4.0\server\下的solr文件夹,到任意目录处(可以重新命名,这里重命名为solr-home,笔者solrhome路径为:E:\solr-home),自定义solrhome。

solr容器 solr7_xml_25

6、配置solrhome路径:修改E:\tomcat\webapps\solr\WEB-INF/下的web.xml文件

<env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>E:/solr-home</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>

7、取消权限控制,注释web.xml中的最后几行代码。否则项目会包403.

<!--
  <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>
  -->

8、启动访问http://localhost:8080/solr/index.html

solr容器 solr7_solr容器_26

 第五、Java 集成SolrJ客户端

Java 项目添加SolrJ jar包依赖:

<!--solrj jar包 -->
		<dependency>
			<groupId>org.apache.solr</groupId>
			<artifactId>solr-solrj</artifactId>
			<version>7.4.0</version>
		</dependency>

1、查询

package com.zzg.solr;

import java.io.IOException;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;

public class SolrTemplateQuery {
	
	public static HttpSolrClient getHttpSolrClient(String solrUrl) {
		HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrUrl)
				.withConnectionTimeout(5000)//设置连接超时时间
				.withSocketTimeout(5000).build();
		return httpSolrClient;
	}
	
	public static SolrQuery getSolrQuery(Integer start, Integer rows, String... fq) {
		SolrQuery query = new SolrQuery();//创建SolrQuery对象
		query.set("q", "*:*");
		query.setFilterQueries(fq);
		query.setStart(start);
		query.setRows(rows);
		return query;
	}
	
	public static void getResponse(HttpSolrClient solrClient, SolrQuery query) throws SolrServerException, IOException {
		QueryResponse response = solrClient.query(query);//创建QueryResponse对象
		//获取SolrDocument列表
		SolrDocumentList docList = response.getResults();
		System.out.println("文档数据条数是:" + docList.getNumFound());
		//遍历SolrDocumentList
		for (SolrDocument document : docList) {
			System.out.println("id:" + document.getFieldValue("id"));
			System.out.println("title:" + document.getFieldValue("title"));
			System.out.println("content:" + document.getFieldValue("content"));
			System.out.println("authorId:" + document.getFieldValue("authorId"));
			System.out.println("-------------------------------------");
		}

	}
	
	public static void main(String[] args) throws SolrServerException, IOException {
		HttpSolrClient solrClient = getHttpSolrClient("http://127.0.0.1:8080/solr/good");
		SolrQuery query = getSolrQuery(0, 10, new String[] {"title:java","content:笔记"});
		getResponse(solrClient, query);
	}
	
	

}

2、新增

package com.zzg.solr;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.common.SolrInputDocument;

public class SolrTemplateInsert {
	
	public static HttpSolrClient getHttpSolrClient(String solrUrl) {
		HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrUrl)
				.withConnectionTimeout(5000)//设置连接超时时间
				.withSocketTimeout(5000).build();
		return httpSolrClient;
	}
	
	public static SolrInputDocument  getSolrInputDocument(Map<String, Object> parameter) {
		SolrInputDocument document = new SolrInputDocument();
		parameter.forEach((k,v)->{
			document.addField(k, v);
		});
		return document;
	}
	public static void main(String[] args) throws SolrServerException, IOException {
		// TODO Auto-generated method stub
		Map<String, Object> parameter = new HashMap<String, Object>();
		parameter.put("categoryId", "1");
		parameter.put("pubTime", new Date());
		parameter.put("id", "10");
		parameter.put("title","三国演义");
		parameter.put("authorId", "1");
		parameter.put("content", "三国演义");
		
		HttpSolrClient solrClient = getHttpSolrClient("http://127.0.0.1:8080/solr/good");
		SolrInputDocument document = getSolrInputDocument(parameter);
		solrClient.add(document);
		solrClient.commit();
	}

}

3、修改

package com.zzg.solr;

import java.io.IOException;
import java.util.Map;

import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.common.SolrInputDocument;

public class SolrTemplateUpdate {
	
	public static HttpSolrClient getHttpSolrClient(String solrUrl) {
		HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrUrl).withConnectionTimeout(5000)// 设置连接超时时间
				.withSocketTimeout(5000).build();
		return httpSolrClient;
	}
	
	public static SolrInputDocument  getSolrInputDocument(String id, String key, Object value) {
		SolrInputDocument document = new SolrInputDocument();
		document.addField("id", id);
		document.addField(key, value);
		return document;
	}

	public static void main(String[] args) throws SolrServerException, IOException {
		// TODO Auto-generated method stub
		HttpSolrClient solrClient = getHttpSolrClient("http://127.0.0.1:8080/solr/good");
		SolrInputDocument document = getSolrInputDocument("10","title","三国演义-修改");
		solrClient.add(document);
		solrClient.commit();
		
	}

}

4、删除

package com.zzg.solr;

import java.io.IOException;

import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;

public class SolrTemplateDelete {
	
	public static HttpSolrClient getHttpSolrClient(String solrUrl) {
		HttpSolrClient httpSolrClient = new HttpSolrClient.Builder(solrUrl)
				.withConnectionTimeout(5000)//设置连接超时时间
				.withSocketTimeout(5000).build();
		return httpSolrClient;
	}

	public static void main(String[] args) throws SolrServerException, IOException {
		// TODO Auto-generated method stub
		HttpSolrClient solrClient = getHttpSolrClient("http://127.0.0.1:8080/solr/good");
		solrClient.deleteById("10");
		solrClient.commit();
	}

}