一 。solr简介
solr是以lucene为内核开发的企业级搜索应用 应用程序可以通过http请求方式来提交索引,查询索引,提供了比lucene更丰富的查询语言,是
一个高性能,高可用环境全文搜索引擎
二 。solr安装配置
1》下载solr安装包 solr所有版本 (http://archive.apache.org/dist/lucene/solr/) 这里下载 solr-5.5.5
2》安装 解压将solr-5.5.5\server\solr-webapp下的webapp 拷贝到tomcat\webapps目录下 改名为solr 启动tomcat
直接访问 出现404 找到tomcat/logs/localhost.2017-08-17.log 日志 出现以下异常
java.lang.NoClassDefFoundError: Failed to initialize Apache Solr: Could not find necessary SLF4j logging jars.
If using Jetty, the SLF4j logging jars need to go in the jetty lib/ext directory. For other containers,
the corresponding directory should be used. For more information, see: http://wiki.apache.org/solr/SolrLogging at org.apache.solr.servlet.CheckLoggingConfiguration.check(CheckLoggingConfiguration.java:27)
at org.apache.solr.servlet.BaseSolrFilter.<clinit>(BaseSolrFilter.java:30)
可用看到缺少SLF4j包 应该去 应该去 解压包 /server/lib/ext下找到并拷贝到 tomcat/solr/lib目录下 然后重启
继续访问 出现以下错误
java.lang.NoSuchMethodError: javax.servlet.ServletInputStream.isFinished()Z
org.apache.solr.servlet.SolrDispatchFilter.consumeInputFully(SolrDispatchFilter.java:284)
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:274)
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:208)
明显是Servlet版本不一致 tomcat6不支持solr5.54 加大tomcat版本 tomcat7也不支持 换成tomcat8 启动后访问 依然错误:
org.apache.solr.common.SolrException: Error processing the request. CoreContainer is either not initialized or shutting down.
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:217)
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:208)
因为需要配置solrhome和solrhome的配置环境
3》配置solrhome
找到 tomcat\solr\WEB-INF\web.xml 编辑 找到以下这段(配置solrhome) 去掉注释 将第二个参数配置为本地任意一个目录即可
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>D:\learn\solr-5.5.4\home</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
找到solr解压包/server/solr目录拷贝所有文件到 以上web.xml指定的路径
D:\learn\solr-5.5.5\home下 重启tomcat 访问
http://localhost:8080/solor/index.html 或者 http://localhost:8080/solr/admin.html
pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.ps</groupId>
<artifactId>Solr</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency> <!-- 分词器,附带引入下面三个jar,版本为4.7.2不支持中文分词,此处需要5.5.5故需单独引入下列包-->
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.5.5</version>
</dependency>
</dependencies>
</project>
4》修改源代码,因为ik 2012年停止更新,仅支持4.7,此处需要5.5.5版本,故需修改源代码,同包,同类,同方法,会覆盖,调用时优先调用项目自己定义的
新建包与jar包该类一致的名字,并拷贝这两个类
修改IKAnalyzer类此方法
@Override
protected TokenStreamComponents createComponents(String fieldName, final Reader in) {
Tokenizer _IKTokenizer = new IKTokenizer(in, this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}
修改为下图方法内容
@Override
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer _IKTokenizer = new IKTokenizer( this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}
修改IKTokenizer
//修改前
public IKTokenizer(Reader in, boolean useSmart) {
super(in);
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}
//修改后
public IKTokenizer(boolean useSmart) {
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}
将这两个的class文件替换到jar包中
用压缩工具打开jar包ikanalyzer-2012_u6.jar
路径:ikanalyzer-2012_u6.jar\org\wltea\analyzer\lucene
替换这两个文件即可
点击Add core后 成功后 检查 mycore目录 发现多了 core.properties和data两个资源
登陆solr管理网站发现 列表中多了mycore
5 》配置文件理解
core/conf目录下的两个配置文件非常重要
managed-schema 主要用于配置 可以提交到该core的所有field定义,field的类型定义,唯一标识符等
常用配置如下:
定义字段 _version_ 类型为long indexed="true" 会进行分词索引 stored="true"表示存储到磁盘
<field name="_version_" type="long" indexed="true" stored="true"/>
定义字段 id required="true" 表示所有的document必须添加id字段 multiValued="false" 表示是否是多值字段
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
定义动态字段 所以_i结尾的字段都可以写入到当前的core
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
定义唯一标识符的字段
<uniqueKey>id</uniqueKey>
定义字段类型的别名
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
solrconfig.xml 主要用于配置solor的主要配置信息 比如lucene版本 缓存 数据目录 请求路径映射 等
表示lucene版本
<luceneMatchVersion>5.5.5</luceneMatchVersion>
表示数据目录 默认是data目录
<dataDir>${solr.data.dir:}</dataDir>
自动提交配置
<autoCommit>
当超过15000ms后自动提交所有数据
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
是否马上就可以查询到
<openSearcher>false</openSearcher>
</autoCommit>
表示当路径为 /select时查询所有的数据
<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these
will be overridden by parameters in the request
-->
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
</lst>
</requestHandler>
尝试在界面上添加数据和查询数据
添加数据
查询的参数列表
q表示查询的条件 字段名:值的格式 多个条件组合查询可以使用 字段:字段值 && 字段1:字段值1 也可以使用大写的AND或者OR
fq表示filter query 过滤条件 和q是and的关系支持各种逻辑运算符 (参考https://cwiki.apache.org/confluence/display/solr/The+Standard+Query+Parser)
sort表示排序 的字段 字段名 asc|desc
start 表示从第几行开始 rows表示查询的总行数
fl表示查询显示的列 比如只需要查询 name_s,sex_i 这两列 使用,隔开
df表示默认的查询字段 一般不设置
Raw Query Parameters表示原始查询字段 可以使用 start=0&rows=10这种url的方式传入参数
wt(write type)表示写入的格式 可以使用json和xml
shards 多核同时搜索 solrhome拷贝mycore为mycore1 管理平台添加core 设置参数为 路径,路径来设置需要搜索的核
String shards = “localhost:8080/solr/mycore,localhost:8080/solr/mycore1”;
query.set(“shards”, shards);
其他参考(https://cwiki.apache.org/confluence/display/solr/Common+Query+Parameters)
将solrhome下 配置文件managed-schema 添加一个字段类型 使用ik分词器
<fieldType name="text_ik" class="solr.TextField" >
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
不能修改 StrField 不支持自定义分词器
<fieldType name="string" class="solr.StrField" sortMissingLast="true" > </fieldType>
然后将对应需要进行中文分词的字段使用 text_ik该字段类型 比如
重启 或者 cloud环境下重新生成collection 插入数据即可实现中文分词 通过某些中文关键字搜索创建配置data-conf.xml
<?xml version="1.0" encoding="UTF8"?>
<dataConfig>
<dataSource name="source1" type="JdbcDataSource" driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.0.250:3306/school" user="root" password="ps123456" batchSize="-1" />
<document> <!-- 自动导入要查询表的数据 -->
<entity name="book" pk="newid" dataSource="source1" query="select * from mytext" >
<field column="newid" name="id"/>
<field column="newtitle" name="title_ik"/>
</entity>
</document>
</dataConfig>
添加到solrconfig.xml,并一同拷贝到mycore1 核的配置目录
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-conf.xml</str>
</lst>
</requestHandler>
拷回去
docker cp ./data-conf.xml my_solr:/opt/solr/server/solr/mycore1/conf
docker cp ./solrconfig.xml my_solr:/opt/solr/server/solr/mycore1/conf
managed-schema 拷出来,新增如下配置,在拷回去
docker cp my_solr:/opt/solr/server/solr/mycore1/conf/managed-schema ./
改完后拷回去
docker cp ./managed-schema my_solr:/opt/solr/server/solr/mycore1/conf/
<fieldType name="text_ik" class="solr.TextField" >
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
<dynamicField name="*_ik" type="text_ik" indexed="true" stored="true"/>
访问solrweb管理界面 http://ip:
mysql数据
页面查询数据
支持数据库语句,关键字必须大写
java代码查询
控制层
@RestController
public class SolrControll {
@Autowired
private SolrTemplate temp;
@GetMapping("/que")
public List<Entity> news(String keyword) {
SimpleQuery siq=new SimpleQuery("title_ik:"+keyword);
System.out.println(keyword+"------------");
Page<Entity> query=temp.query(siq, Entity.class);
return query.getContent();
}
}
pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<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>
properties
spring.data.solr.host=http://192.168.174.131:8983/solr
server.port=8888
页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>什么鬼页面</title>
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"></script>
<script type="text/javascript">
function query(){
$.ajax({
url:"que",
dataType:"json",
type:"get",
data:"keyword="+$("#keys").val(),
success:function(r){
$("#mynews").text(JSON.stringify(r));
}
});
}
</script>
</head>
<body>
<div>新闻:<input id="keys" type="text"name="keyword" ></div>
<button onclick="query()">搜索</button>
<div id="mynews"> </div>
</body>
</html>