快速入门全文搜索服务 -- solr 7.4.0 (有java的增删改查代码)

参考:https://blog.csdn.net/l1336037686/article/details/80723636

solr图示简介

在这里插入图片描述

看了上面的图示介绍,你可能会问,那数据库在solr中有什么用呢?是不是有了solr的索引库我们就不需要建立数据库了呢?

其实不然
第一,数据库可以作为索引库数据的备份,当索引库损坏时,可以将数据库中的数据导入到索引库中。
第二,当你要升级solr的版本,这时候原来的索引库已经不能够兼容solr新的版本了,怎么办?没错,从数据库中导入。

在tomcat上部署solr

[solr下载](http://lucene.apache.org/solr/mirrors-solr-latest-redir.html)
下载solr后我们可以看到它的目录结构

这里写图片描述

solr内置了一个jetty服务器,我们不使用它,使用tomcat服务器。



(1)复制solr-7.4.0/server/solr-webapp目录下的webapp文件复制到一个tomcat服务器的webapp目录下,并且重命名为solr。(目的是将solr项目发布)
这里写图片描述

这里写图片描述

(2)接下来,将solr-7.4.0/server/lib下以m开头的jar、gmetric4j-1.0.7.jar包和ext下所有的包拷贝到tomcat的webapps/solr/WEB-INF/lib下
这里写图片描述

这里写图片描述

这里写图片描述


(3)拷贝solr-7.4.0/server/resources下的log4j2.xml到webapps/solr/WEB-INF目录下的classes(没有classes文件就创建一个) 注:步骤3、6、9、10是配置solr的日志,不做也可

这里写图片描述
这里写图片描述



(4)复制solr-7.4.0/server/下的solr到任意地方,并取名solr_home(取名任意),这是存放索引库的地方。并在tomcat中webapp/solr/WEB-INF/web.xml中配置solr_home的路径,打开web.xml,在第41行找到并解开<env-entry>的注释,并配置<env-entry-value>为你自己的solr_home路径。

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




(5)然后翻到web.xml的最后几行代码,注释掉他们,取消权限控制。
这里写图片描述



(6)复制solr-7.4.0目录下的contrib和dist到solr_home下。(配置日志)
这里写图片描述



(7)在solr_home目录下创建一个文件夹(它对应数据库中的表),名字任意,这里我们取名为goods。然后将configsets/_default下的conf文件夹复制到新建的goods文件夹下,并在goods目录下创建文件夹data。

这里写图片描述

这里写图片描述

这里写图片描述



(8)然后再在goods目录下创建文件core.properties,内容为name=goods
这里写图片描述



(9)打开tomcat下bin目录的catalian.bat,在206行的代码块最后添加一行代码。(配置日志)
这里写图片描述

if not "%JSSE_OPTS%" == "" goto gotJsseOpts
set JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048"
:gotJsseOpts
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%" 
-- 下面一行是新增的,D:\csdn\solr\solr_home\log为你存放日志的路径
set "JAVA_OPTS=%JAVA_OPTS% -Dsolr.log.dir=D:\csdn\solr\solr_home\log" 




(10)将solr_home/goods/conf下的solrconfig.xml的第76到86行改为:(可以注释掉再添加)(配置日志)

<lib dir="${solr.install.dir:../}/contrib/extraction/lib" regex=".*\.jar" />  
<lib dir="${solr.install.dir:../}/dist/" regex="solr-cell-\d.*\.jar" />  

<lib dir="${solr.install.dir:../}/contrib/clustering/lib/" regex=".*\.jar" />  
<lib dir="${solr.install.dir:../}/dist/" regex="solr-clustering-\d.*\.jar" />  

<lib dir="${solr.install.dir:../}/contrib/langid/lib/" regex=".*\.jar" />  
<lib dir="${solr.install.dir:../}/dist/" regex="solr-langid-\d.*\.jar" />  

<lib dir="${solr.install.dir:../}/contrib/velocity/lib" regex=".*\.jar" />  
<lib dir="${solr.install.dir:../}/dist/" regex="solr-velocity-\d.*\.jar" />  
    
<lib dir="${solr.install.dir:../}/dist/" regex="ojdbc\d.*\.jar" />  
<lib dir="${solr.install.dir:../}/dist/" regex="solr-dataimporthandler\d.*\.jar" />  

下图是要被修改的地方
这里写图片描述



(11)然后双击tomcat中bin下的startup.bat文件,启动tomcat服务器,然后在浏览器中输入网址http://127.0.0.1:8080/solr/index.html 即可访问solr的管理界面。

这里写图片描述

solr管理界面简介

![这里写图片描述](https://img-blog.csdn.net/20180916095538853?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMTU4NDM2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

这里写图片描述

这里写图片描述

索引表字段的添加以及导入数据库中的数据到索引表

(1)我们首先看看数据库中表的字段

这里写图片描述



(2)然后我们给goods索引表配备分词器,并添加字段。先下载ik分词器(智能分词,很好用)链接:https://pan.baidu.com/s/1mirMgX_Dl8u6jNZCnvhp0Q 密码:t9x7。
将ik分词器的jar包放入tomcat的webapps/solr/WEB-INF/lib下。



(3)打开solr_home\goods\conf下的managed-schema文件,我们可以看到113行已经有4个默认字段了,其中包含id。
这里写图片描述

我们在下面添加一些配置

<!-- 配置ik分词器 -->
<fieldType name="text_ik" class="solr.TextField">
	<analyzer type="index">
		<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
		<filter class="solr.LowerCaseFilterFactory"/>
	</analyzer>
	<analyzer type="query">
		<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>
		<filter class="solr.LowerCaseFilterFactory"/>
	</analyzer>
</fieldType>
<!-- 配置字段 -->
<field name="name" type="text_ik" indexed="true" stored="true" multiValued="false" />
<field name="price" type="pdouble" indexed="false" stored="true" multiValued="false" />
<field name="manufacturer" type="text_ik" indexed="true" stored="true" multiValued="false" />

其中,filed的type如果填写配置的分词器的name,就可以使用该分词器分词,如果是string、plong、pdouble就不能被分词,indexed选项是是否建立索引,建立索引后就能被分词搜索,stored是是否存储该数据,multiValued是是否支持多值。

然后我们重启tomcat后进入管理界面就可以看到我们创建的字段了。
这里写图片描述

我们选择type下的text_ik分词器,然后在左边的输入框输入四川成都有什么好玩的地方,可以看到这一句话被分词器分词了。
这里写图片描述



(4)从数据库中导入数据到索引库。
将mysql的驱动mysql-connector-java-5.1.37-bin.jar与solr-7.4.0/dist中的solr-dataimporthandler-7.4.0.jar和solr-dataimporthandler-extras-7.4.0.jar放入apache-tomcat-8.5.27\webapps\solr\WEB-INF\lib下。

这里写图片描述



(5)将solr-7.4.0/example/example-DIH/solr/db/conf下的db-data-config.xml复制到solr_home/goods/conf下。
这里写图片描述

这里写图片描述

并将里面的内容改为

<dataConfig>
    <dataSource type="JdbcDataSource"
				 driver="com.mysql.jdbc.Driver" 
				 url="jdbc:mysql://127.0.0.1:3306/test"
				 user="root"
				 password="root" />
	<document>
		<entity name="goods" 
				query="select id,name,price,manufacturer from goods">
		</entity>
	</document>
</dataConfig>




(6)打开该目录下的solrconfig.xml文件,
这里写图片描述

在1000行左右,添加如下配置,要与<requestHandler>标签同级

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




(7)重启tomcat,进入官网,选择goods索引表,点击Dataimport,然后选择导入的数据库表名字,最后点击Excute,然后刷新一下就(Refresh Status)ok了。

这里写图片描述

数据库中的数据

这里写图片描述

导入数据库后,查询索引表,可以看到有4条数据了

这里写图片描述


代码实现(solrj)solr的增删改查以及查询结果高亮显示

(1)首先创建一个java project工程,导入jar包。将solr-7.4.0/dist中solrj-lib文件夹下的所有jar包与solr-solrj-7.4.0.jar复制到工程lib文件夹下,并build path。

这里写图片描述



工程目录结构
这里写图片描述



(2)实体类

public class Goods {
	private int id;
	private String name;
	private double price;
	private String manufacturer;
	
	// 无参有参构造方法
	// getter setter
	// 重写toString方法
}




(3)GoodsSolrDao中的增加或更新方法

	/**
	 * id不重复则增加,有相同的则更新
	 */
	public void insertOrUpdate(Goods goods) {
        // 创建solrClient同时指定超时时间
        HttpSolrClient client = new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/goods").withConnectionTimeout(10000).build();

        // 创建文档doc
        SolrInputDocument doc = new SolrInputDocument();
        
        // 添加内容
        doc.addField("id", goods.getId());
        doc.addField("name", goods.getName());
        doc.addField("price", goods.getPrice());
        doc.addField("manufacturer", goods.getManufacturer());
        
        // 添加到client,并且提交(commit)
        try {
			client.add(doc);
			client.commit();
		} catch (SolrServerException | IOException e) {
			e.printStackTrace();
		}
	}

TestGoodsSolrDao中的测试方法–测试增加,启动tomcat,执行测试方法

	@Test
	public void testInsertOrUpdate() {
		GoodsSolrDao goodsSolrDao = new GoodsSolrDao();
		Goods goods = new Goods(5, "vivo max3 A", 1800, "vivo");
		goodsSolrDao.insertOrUpdate(goods);
	}

结果,增加成功
这里写图片描述

TestGoodsSolrDao中的测试方法–测试更新(id相同则更新)

	@Test
	public void testInsertOrUpdate1() {
		GoodsSolrDao goodsSolrDao = new GoodsSolrDao();
		Goods goods = new Goods(5, "vivo X23", 3498, "vivo");
		goodsSolrDao.insertOrUpdate(goods);
	}

结果,更新成功
这里写图片描述



(4)GoodsSolrDao中的删除方法

	/**
	 * 删除索引
	 */
	public void delete(int id) {
  	  // 获取连接
  	  HttpSolrClient client = new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/goods").withConnectionTimeout(10000).build();
      try {
    	  // 通过id删除
    	  client.deleteById(String.valueOf(id));
	      // 提交
	      client.commit();
	      // 关闭资源
	      client.close();
      } catch (SolrServerException | IOException e) {
		e.printStackTrace();
      }
	}

TestGoodsSolrDao中的测试方法,启动tomcat,执行测试方法

	@Test
	public void testDelete() {
		GoodsSolrDao goodsSolrDao = new GoodsSolrDao();
		goodsSolrDao.delete(5);
	}

结果,删除成功
这里写图片描述



(5)GoodsSolrDao中的根据关键字name查询的方法

	/**
	 * @param keyWord 搜索的关键句子
	 * @param isHighLight 是否返回高亮对象列表,true则返回高亮对象列表,
	 *	  false返回普通对象列表
	 * @return List<Goods>
	 */
	public List<Goods> search(String keyWord, boolean isHighLight){
    	//创建solrClient同时指定超时时间
		HttpSolrClient client = new HttpSolrClient.Builder("http://127.0.0.1:8080/solr/goods").withConnectionTimeout(10000).build();
		
		// 创建SolrQuery,查询时用到
		SolrQuery solrQuery = new SolrQuery();
		// 设置关键词
		solrQuery.setQuery(keyWord);
		// 过滤条件 
		//solrQuery.set("fq", "price:[0 TO 5000]");// "price:[10 TO *]"
		// 分页
		//solrQuery.setStart(0);
		//solrQuery.setRows(16);
		// 默认搜索字段
		solrQuery.set("df", "name");
		// 只查询指定域 相当于select id,name,price,manufacturer from goods.
		solrQuery.set("fl", "id,name,price,manufacturer");
		// 打开高亮开关
		solrQuery.setHighlight(true);
		// 指定高亮域
		solrQuery.addHighlightField("name");
		// 关键词前缀
		solrQuery.setHighlightSimplePre("<font color='red'>");
		// 关键词后缀
		solrQuery.setHighlightSimplePost("</font>");

		// 执行查询
		QueryResponse response = null;
		try {
			response = client.query(solrQuery);
		} catch (SolrServerException | IOException e) {
			e.printStackTrace();
		}
		// 普通结果集
		SolrDocumentList docs = response.getResults();
		
        // 获取高亮结果集
		// 1.Map<String, Map<String, List<String>>>的key是id,
		//   value是查询到的数据
		// 2.Map<String, List<String>>的key是字段名,value是值,
		//   如果支持多值,它的值就是集合,不支持值就是该集合的第一个元素
		Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
		
		// 总条数
		long totalNum = docs.getNumFound();
		System.out.println("totalNum:"+totalNum);
		
		// 普通查询对象列表
		List<Goods> goods = new ArrayList<Goods>();
		// 高亮查询对象列表
		List<Goods> highLightGoods = new ArrayList<Goods>();
		//遍历结果集
		for (SolrDocument doc : docs) {
			Goods _good = new Goods();
			Goods _highLightGood = new Goods();
			
			// 设置普通结果到_good中
			_good.setId(Integer.valueOf((String)doc.get("id")));
			_good.setName((String)doc.get("name"));
			_good.setPrice((double)doc.get("price"));
			_good.setManufacturer((String)doc.get("manufacturer"));
			
			// 设置高亮结果到_highLightGood中
			// 得到该条数据
			Map<String, List<String>> map = 
			  highlighting.get((String)doc.get("id"));
			// 设置各个字段 不支持多值的字段,
			//   其值就是List<String>中的第一个值
			// 如果被搜索的字段不包含搜索的关键字,则会被置为空,
			//   所以需要判定是否为空,为空则使用普通结果
			_highLightGood.setId(_good.getId());
			String name = map.get("name").get(0);
			_highLightGood.setName(name == null ? _good.getName() : name);
			_highLightGood.setPrice(_good.getPrice());
			_highLightGood.setManufacturer(_good.getManufacturer());
			
			// 将_good与_highLightGood分别添加到普通对象刘表与高亮对象列表中
			goods.add(_good);
			highLightGoods.add(_highLightGood);
		}
		// isHighLight为真,返回高亮对象列表,否则返回普通结果对象列表
		if(isHighLight) {
			return highLightGoods;
		}else {
			return goods;
		}
	}

TestGoodsSolrDao中的测试方法,启动tomcat,执行测试方法

	@Test
	public void testSearch() {
		GoodsSolrDao goodsSolrDao = new GoodsSolrDao();
		List<Goods> goods = goodsSolrDao.search("苹果", true);
		System.out.println(goods);
	}

结果
这里写图片描述

我们可以看到,solr对要搜索的字段name中的“苹果”进行了高亮处理。
但是有一点我要提醒下大家,ik不会对1个数字进行分词,你搜索“苹果8”,只会对”苹果“两字进行高亮处理。
例:
这里写图片描述

但是数字达到两位,它进行分词了,如下
这里写图片描述



非常感谢大家阅读我的博客。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值