一 : solr简介
solr是以lucene为内核开发的企业级搜索应用 应用程序可以通过http请求方式来提交索引,查询索引,提供了比lucene更丰富的查询语言,是一个高性能,高可用环境全文搜索引擎
二:Docker安装solr
核(core):是用于存储json格式的数据,等价于mysql中数据库的概念
文档:一个json对象就是一个文档 相同属性的json数组集合就是一个表
拉取镜像:docker pull solr:5.5.5 (5.5.5为版本号)
运行容器:docker run --name my_solr -id --net host -t solr:5.5.5
检测端口 :netstat -aon | grep 8983(要安装插件:yum -y install net-tools telnet)
创建core:
docker exec -it --user=solr my_solr bin/solr create_core -c mycore
创建完成之后会有一个提示:
Copying configuration to new core instance directory:
/opt/solr/server/solr/mycore
Creating new core 'mycore' using command:
http://localhost:8983/solr/admin/cores?action=CREATE&name=mycore&instanceDir=mycore
{
"responseHeader":{
"status":0, # ‘0’代表创建成功
"QTime":3265}, # ‘3265’代表耗费3265毫秒创建成功
"core":"mycore"} # core 的名字叫 ‘mycore’
在谷歌浏览器输入:
192.168.85.128:8983/solr;可以看到:
选中数据库:“mycore”,然后往里面插入json数据(对象):
再查询:
全文匹配搜索效果:
全文匹配搜索效果:
默认solr 没有使用中文分词器 所有搜索的词 都是整个句子就是一个词 搜索时 将单词全部写入才能搜索或者使用* 需要配置中文分词器,目前比较好用的分词器 是IK 2012年停更 只支持到 Lucene4.7 所有 solr5.5 需要lucene5支持 ,需要修改部分源码来支持solr5.5
因为solr的底层是lucene实现的,所以引入依赖之后能看到lucene-core的jar包
步骤:
Ctrl+shift+T: 找到 IKAnalyzer类 ,(复制源码)需要重写 protected TokenStreamComponents createComponents(String fieldName) 方法,
找到 IKTokenizer类 ,(复制源码)需要重写 构造方法 public IKTokenizer(Reader in, boolean useSmart) 为 public IKTokenizer(boolean useSmart) { }
下一步:
将此jar包复制到桌面用解压工具打开:
复制本项目工作区的class文件
找到jar包里的两个 class 文件删除,把上面的两个class文件替换进来
替换好class文件的jar包是支持中文分词的!
下一步:把jar包上传到Linux
进入my_solr容器,把Linux 的 jar 包拷贝到此目录(WEB-INF/lib)下:
复制命令:
docker cp ./ikanalyzer-2012_u6.jar my_solr:/opt/solr/server/solr-webapp/webapp/WEB-INF/lib
把 my_solr 容器里面的managed-scheme文件拷贝到 opt/ika 目录下,修改其中的一些配置, 修改好配置的文件再次拷贝回容器(重点操作):
完成之后,我们再插入一条json数据:
然后再查询:
接下来的重点操作:
数据库数据迁移solr:
进入容器:docker exec -it my_solr bash
拷贝jar包:
cp /opt/solr/dist/solr-dataimporthandler-5.5.5.jar /opt/solr/server/solr-webapp/webapp/WEB-INF/lib
cp /opt/solr/dist/solr-dataimporthandler-extras-5.5.5.jar /opt/solr/server/solr-webapp/webapp/WEB-INF/lib
导入mysql 的驱动 jar包:
把mysql 驱动jar包拷贝到my_solr容器/opt/solr/server/solr-webapp/webapp/WEB-INF/lib目录:
docker cp ./mysql-connector-java-5.1.24.jar my_solr:/opt/solr/server/solr-webapp/webapp/WEB-INF/lib
然后在此文件夹新建一个xml 文件(直接在notepad++工具新建data-conf.xml文件):
配置改为自己的ip和数据库
<?xml version="1.0" encoding="UTF-8"?>
<dataConfig>
<dataSource name="source1" type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.0.124:3306/school" user="root" password="ps123456" batchSize="-1" />
<document>
<entity name="book" pk="newid" dataSource="source1"
query="select * from mynew" >
<field column="newid" name="id"/>
<field column="newtitle" name="newtitle_ik"/>
</entity>
</document>
</dataConfig>
再次访问搜索页面,可以按照标题和ID进行搜索,而且可以按照自定义进行搜索(数据库一般都是升序排序):
三:springBoot集成solr;
添加springBoot的maven依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
</dependencies>
这里可能会有版本冲突的问题,建议把JDK版本换成10以下:
solr配置文件:
spring:
data:
solr:
host: http://192.168.85.128:8983/solr
server:
port: 8888
添加实体类 :
package cn.entiry;
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.solr.core.mapping.SolrDocument;
@SolrDocument(solrCoreName="mycore")
public class News {
private String id;
@Field("newtitle_ik")
private String newtitle;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNewtitle() {
return newtitle;
}
public void setNewtitle(String newtitle) {
this.newtitle = newtitle;
}
}
控制层:
package cn.solrController;
import java.util.List;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.web.bind.annotation.GetMapping;
import cn.entiry.News;
@RestController
public class SolrController {
@Autowired
private SolrTemplate st;
@GetMapping("/queryNews")
public List<News> queryNews(String keyword ){
SimpleQuery sq=new SimpleQuery("newtitle_ik:"+keyword);
Page<News> query = st.query(sq, News.class);
return query.getContent();
}
}
前端页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script>
function query(){
$.ajax({
url:'queryNews',
dataType:'json',
type:'get',
data:'keyword='+$("#mykeyword").val(),
success:function(r){
$("#myNews").text(JSON.stringify(r));
}
});
}
</script>
</head>
<body>
新闻:<input id="mykeyword" type="text" name="keyword"><button onclick="query()">搜索</button>
<div id="myNews">
</div>
</body>
</html>
运行结果:
第四部分:按照指定内容进行搜索
(1)按照内容描述搜索:
我们先存入模拟数据:
{"id":"1","country_s":"美国","provice_s":"加利福尼亚州","city_ik":"旧金山","age_i":"30","name_s":"John","desc_ik":"John is come from austrina John,s Dad is Johh Super"}
{"id":"2","country_s":"美国","provice_s":"加利福尼亚州","city_ik":"好莱坞","age_i":"40","name_s":"Mike","desc_ik":"Mike is come from austrina Mike,s Dad is Mike Super"}
{"id":"3","country_s":"美国","provice_s":"加利福尼亚州","city_ik":"圣地牙哥","age_i":"50","name_s":"Cherry","desc_ik":"Cherry is come from austrina Cherry,s Dad is Cherry Super"}
{"id":"4","country_s":"美国","provice_s":"德克萨斯州","city_ik":"休斯顿","age_i":"60","name_s":"Miya","desc_ik":"Miya is come from austrina Miya,s Dad is Miya Super"}
{"id":"5","country_s":"美国","provice_s":"德克萨斯州","city_ik":"大学城","age_i":"70","name_s":"fubos","desc_ik":"fubos is come from austrina fubos,s Dad is fubos Super"}
{"id":"6","country_s":"美国","provice_s":"德克萨斯州","city_ik":"麦亚伦","age_i":"20","name_s":"marry","desc_ik":"marry is come from austrina marry,s Dad is marry Super"}
{"id":"7","country_s":"中国","provice_s":"湖南省","city_ik":"长沙市","age_i":"18","name_s":"张三","desc_ik":"张三来自长沙市 是公务员一名"}
{"id":"8","country_s":"中国","provice_s":"湖南省","city_ik":"岳阳市","age_i":"15","name_s":"李四","desc_ik":"李四来自岳阳市 是一名清洁工"}
{"id":"9","country_s":"中国","provice_s":"湖南省","city_ik":"株洲市","age_i":"33","name_s":"李光四","desc_ik":"李光四 老家岳阳市 来自株洲 是李四的侄子"}
{"id":"10","country_s":"中国","provice_s":"广东省","city_ik":"深圳市","age_i":"67","name_s":"王五","desc_ik":"王五来自深圳市 是来自深圳的一名海关缉私精英"}
{"id":"11","country_s":"中国","provice_s":"广东省","city_ik":"广州市","age_i":"89","name_s":"王冠宇","desc_ik":"王冠宇是王五的儿子"}
然后再到页面搜索:
但是要如何在代码中实现呢?我们在一个简单的界面输入搜索关键字:
实体类:
@SolrDocument(solrCoreName="mycore")
public class Preson {
private String id;
@Field("country_s")
private String country;
@Field("name_s")
private String name;
@Field("desc_ik")
private String desc;
接口类:
public interface PresonDao extends SolrCrudRepository<Preson, String>{
//按照描述查询
public List<Preson> findByDesc(String keyword);
//按照姓名查询,跟方法名无关
@Query("name_s:?0")
public List<Preson> qurey(String keyword);
}
控制层:
@RestController
public class SolrController {
/*@Autowired
private SolrTemplate st;*/
@Autowired
private PresonDao dao;
@GetMapping("/queryNews")
public List<Preson> queryNews(String keyword ){
/*SimpleQuery sq=new SimpleQuery("newtitle_ik:"+keyword);
Page<News> query = st.query(sq, News.class);
*/
//按照描述查询
List<Preson> findByD = dao.findByDesc(keyword);
//按照姓名查询,跟方法名无关
//List<Preson> findByD = dao.qurey(keyword);
return findByD;
}
}