参考: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”,只会对”苹果“两字进行高亮处理。
例:
但是数字达到两位,它进行分词了,如下
非常感谢大家阅读我的博客。