原文:http://blog.csdn.net/liaomin416100569/article/details/77301756
lucene中的一个document相当于一个对象(object),它也有一个至多个属性(field)
分词器:将存入的数据分成有意义的词
停(用)止词:无意义的词,搜索引擎中搜不出来的词
Lucene使用倒排索引,通过分词器分出来的词作为索引和数据做关联,指向文档
一.solr简介
solr是以lucene为内核开发的企业级搜索应用, 应用程序可以通过http请求方式来提交索引,
查询索引,提供了比lucene更丰富的查询语言,是一个高性能,高可用环境全文搜索引擎
二. solr安装配置
1.下载solr安装包 solr所有版本 (http://archive.apache.org/dist/lucene/solr/)
这里下载 solr-5.5.4
2.安装,解压solr包(这里Tomcat的版本必须>=8以上版本)
1)将solr-5.5.4\server\solr-webapp下的webapp 拷贝到tomcat\webapps目录下 改名为solr
2)将solr-5.5.4\server\lib\ext下的jar包都拷贝到 tomcat\webapps\solr\WEB-INF\lib目录下
3) 配置solrhome
找到 tomcat\solr\WEB-INF\web.xml 编辑 找到以下这段
去掉注释 将第二个参数配置为本地任意一个目录即可
<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>
4) 配置core
注意:需要先将solr解压包下\server\solr下的所有文件拷贝到solrhome(不用做修改修改)
拷贝 solr解压包下\server\solr\configsets\basic_configs目录到solrhome,
直接修改basic_configs目录的名字,修改后的名字就是core的名字(这里core的名字定义为mycore)
启动Tomcat,访问solr的管理界面:http://localhost:8080/solr/admin.html
进入solr管理网页 点击 core admin 添加该core
name和instanceDir都修改成core的名字
点击Add core后 成功后 检查 mycore目录 发现多了 core.properties和data两个资源
5)配置文件理解
core/conf目录下的两个配置文件非常重要
managed-schema(该文件中可以自定义字段) 主要用于配置
可以提交到该core的所有field定义,field的类型定义,唯一标识符等
#自定义字段<field name="字段名" type="数据类型(存在的数据类型)" indexed="true代表分词false代表不分词" stored="true代表存储fasle代表不存储"/>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
solrconfig.xml(该文件不需要修改)
主要用于配置solor的主要配置信息 比如lucene版本 缓存 数据目录 请求路径映射 等
表示lucene版本
<luceneMatchVersion>5.5.4</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>
二. solr配置中文分词器
新建maven项目,pom.xml配置:
<dependencies>
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
<!-- 排除旧版本的jar包 -->
<exclusions>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-sandbox</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 重新引入jar包,版本与使用的solr的版本一致 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-sandbox</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.5.4</version>
</dependency>
</dependencies>
Ctrl+Shift+t :IKAnalyzer 查看该类的源代码
1.新建一个包,包名与IKAnalyzer类的包名一致
拷贝IKAnalyzer类到该包中
拷贝IKTokenizer类到该包中
解决报错的问题:
查看IKAnalyzer的父类,删除类中父类中没有出现的代码
查看IKTokenizer的父类,删除类中父类中没有出现的代码
package org.wltea.analyzer.lucene;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
/**
* IK鍒嗚瘝鍣紝Lucene Analyzer鎺ュ彛瀹炵幇
* 鍏煎Lucene 4.0鐗堟湰
*/
public final class IKAnalyzer extends Analyzer {
private boolean useSmart;
public boolean useSmart() {
return useSmart;
}
public void setUseSmart(boolean useSmart) {
this.useSmart = useSmart;
}
/**
* IK鍒嗚瘝鍣↙ucene Analyzer鎺ュ彛瀹炵幇绫�
*
* 榛樿缁嗙矑搴﹀垏鍒嗙畻娉�
*/
public IKAnalyzer() {
this(false);
}
/**
* IK鍒嗚瘝鍣↙ucene Analyzer鎺ュ彛瀹炵幇绫�
*
* @param useSmart 褰撲负true鏃讹紝鍒嗚瘝鍣ㄨ繘琛屾櫤鑳藉垏鍒�
*/
public IKAnalyzer(boolean useSmart) {
super();
this.useSmart = useSmart;
}
/**
* 閲嶈浇Analyzer鎺ュ彛锛屾瀯閫犲垎璇嶇粍浠�
*/
@Override
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer _IKTokenizer = new IKTokenizer(this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}
}
package org.wltea.analyzer.lucene;
import java.io.IOException;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
/**
* IK鍒嗚瘝鍣� Lucene Tokenizer閫傞厤鍣ㄧ被
* 鍏煎Lucene 4.0鐗堟湰
*/
public final class IKTokenizer extends Tokenizer {
// IK鍒嗚瘝鍣ㄥ疄鐜�
private IKSegmenter _IKImplement;
// 璇嶅厓鏂囨湰灞炴��
private final CharTermAttribute termAtt;
// 璇嶅厓浣嶇Щ灞炴��
private final OffsetAttribute offsetAtt;
// 璇嶅厓鍒嗙被灞炴�э紙璇ュ睘鎬у垎绫诲弬鑰僶rg.wltea.analyzer.core.Lexeme涓殑鍒嗙被甯
搁噺锛�
private final TypeAttribute typeAtt;
// 璁板綍鏈�鍚庝竴涓瘝鍏冪殑缁撴潫浣嶇疆
private int endPosition;
/**
* Lucene 4.0 Tokenizer閫傞厤鍣ㄧ被鏋勯�犲嚱鏁�
* @param in
* @param useSmart
*/
public IKTokenizer(boolean useSmart) {
super();
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}
/*
* (non-Javadoc)
* @see org.apache.lucene.analysis.TokenStream#incrementToken()
*/
@Override
public boolean incrementToken() throws IOException {
// 娓呴櫎鎵�鏈夌殑璇嶅厓灞炴��
clearAttributes();
Lexeme nextLexeme = _IKImplement.next();
if (nextLexeme != null) {
// 灏哃exeme杞垚Attributes
// 璁剧疆璇嶅厓鏂囨湰
termAtt.append(nextLexeme.getLexemeText());
// 璁剧疆璇嶅厓闀垮害
termAtt.setLength(nextLexeme.getLength());
// 璁剧疆璇嶅厓浣嶇Щ
offsetAtt.setOffset(nextLexeme.getBeginPosition(), nextLexeme.getEndPosition());
// 璁板綍鍒嗚瘝鐨勬渶鍚庝綅缃�
endPosition = nextLexeme.getEndPosition();
// 璁板綍璇嶅厓鍒嗙被
typeAtt.setType(nextLexeme.getLexemeTypeString());
// 杩斾細true鍛婄煡杩樻湁涓嬩釜璇嶅厓
return true;
}
// 杩斾細false鍛婄煡璇嶅厓杈撳嚭瀹屾瘯
return false;
}
/*
* (non-Javadoc)
* @see org.apache.lucene.analysis.Tokenizer#reset(java.io.Reader)
*/
@Override
public void reset() throws IOException {
super.reset();
_IKImplement.reset(input);
}
@Override
public final void end() {
// set final offset
int finalOffset = correctOffset(this.endPosition);
offsetAtt.setOffset(finalOffset, finalOffset);
}
}
2.找到本地maven仓库中ikanalyzer-2012_u6.jar
复制到本地,删除jar包中ikanalyzer-2012_u6.jar\org\wltea\analyzer\lucene
的两个class文件:IKAnalyzer.class ,IKTokenizer.class
在本地代码的存放目录中找到项目中自己重写两个类的class文件(target目录),拷贝至
ikanalyzer-2012_u6.jar\org\wltea\analyzer\lucene
最后将jar包复制到solr\WEB-INF\lib目录下
solrhome\mycore\conf\managed-schema配置:
<!--定义动态类型-->
<dynamicField name="*_ik" type="text_ik" indexed="true" stored="true" />
<!--定义支持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"/>
lucene中的一个document相当于一个对象(object),它也有一个至多个属性(field)
分词器:将存入的数据分成有意义的词
停(用)止词:无意义的词,搜索引擎中搜不出来的词
Lucene使用倒排索引,通过分词器分出来的词作为索引和数据做关联,指向文档
一.solr简介
solr是以lucene为内核开发的企业级搜索应用, 应用程序可以通过http请求方式来提交索引,
查询索引,提供了比lucene更丰富的查询语言,是一个高性能,高可用环境全文搜索引擎
二. solr安装配置
1.下载solr安装包 solr所有版本 (http://archive.apache.org/dist/lucene/solr/)
这里下载 solr-5.5.4
2.安装,解压solr包(这里Tomcat的版本必须>=8以上版本)
1)将solr-5.5.4\server\solr-webapp下的webapp 拷贝到tomcat\webapps目录下 改名为solr
2)将solr-5.5.4\server\lib\ext下的jar包都拷贝到 tomcat\webapps\solr\WEB-INF\lib目录下
3) 配置solrhome
找到 tomcat\solr\WEB-INF\web.xml 编辑 找到以下这段
去掉注释 将第二个参数配置为本地任意一个目录即可
<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>
4) 配置core
注意:需要先将solr解压包下\server\solr下的所有文件拷贝到solrhome(不用做修改修改)
拷贝 solr解压包下\server\solr\configsets\basic_configs目录到solrhome,
直接修改basic_configs目录的名字,修改后的名字就是core的名字(这里core的名字定义为mycore)
启动Tomcat,访问solr的管理界面:http://localhost:8080/solr/admin.html
进入solr管理网页 点击 core admin 添加该core
name和instanceDir都修改成core的名字
点击Add core后 成功后 检查 mycore目录 发现多了 core.properties和data两个资源
5)配置文件理解
core/conf目录下的两个配置文件非常重要
managed-schema(该文件中可以自定义字段) 主要用于配置
可以提交到该core的所有field定义,field的类型定义,唯一标识符等
#自定义字段<field name="字段名" type="数据类型(存在的数据类型)" indexed="true代表分词false代表不分词" stored="true代表存储fasle代表不存储"/>
定义字段 _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.4</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>
二. solr配置中文分词器
新建maven项目,pom.xml配置:
<dependencies>
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
<!-- 排除旧版本的jar包 -->
<exclusions>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-sandbox</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 重新引入jar包,版本与使用的solr的版本一致 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-sandbox</artifactId>
<version>5.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.5.4</version>
</dependency>
</dependencies>
Ctrl+Shift+t :IKAnalyzer 查看该类的源代码
1.新建一个包,包名与IKAnalyzer类的包名一致
拷贝IKAnalyzer类到该包中
拷贝IKTokenizer类到该包中
解决报错的问题:
查看IKAnalyzer的父类,删除类中父类中没有出现的代码
查看IKTokenizer的父类,删除类中父类中没有出现的代码
package org.wltea.analyzer.lucene;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
/**
* IK鍒嗚瘝鍣紝Lucene Analyzer鎺ュ彛瀹炵幇
* 鍏煎Lucene 4.0鐗堟湰
*/
public final class IKAnalyzer extends Analyzer {
private boolean useSmart;
public boolean useSmart() {
return useSmart;
}
public void setUseSmart(boolean useSmart) {
this.useSmart = useSmart;
}
/**
* IK鍒嗚瘝鍣↙ucene Analyzer鎺ュ彛瀹炵幇绫�
*
* 榛樿缁嗙矑搴﹀垏鍒嗙畻娉�
*/
public IKAnalyzer() {
this(false);
}
/**
* IK鍒嗚瘝鍣↙ucene Analyzer鎺ュ彛瀹炵幇绫�
*
* @param useSmart 褰撲负true鏃讹紝鍒嗚瘝鍣ㄨ繘琛屾櫤鑳藉垏鍒�
*/
public IKAnalyzer(boolean useSmart) {
super();
this.useSmart = useSmart;
}
/**
* 閲嶈浇Analyzer鎺ュ彛锛屾瀯閫犲垎璇嶇粍浠�
*/
@Override
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer _IKTokenizer = new IKTokenizer(this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}
}
package org.wltea.analyzer.lucene;
import java.io.IOException;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
/**
* IK鍒嗚瘝鍣� Lucene Tokenizer閫傞厤鍣ㄧ被
* 鍏煎Lucene 4.0鐗堟湰
*/
public final class IKTokenizer extends Tokenizer {
// IK鍒嗚瘝鍣ㄥ疄鐜�
private IKSegmenter _IKImplement;
// 璇嶅厓鏂囨湰灞炴��
private final CharTermAttribute termAtt;
// 璇嶅厓浣嶇Щ灞炴��
private final OffsetAttribute offsetAtt;
// 璇嶅厓鍒嗙被灞炴�э紙璇ュ睘鎬у垎绫诲弬鑰僶rg.wltea.analyzer.core.Lexeme涓殑鍒嗙被甯
搁噺锛�
private final TypeAttribute typeAtt;
// 璁板綍鏈�鍚庝竴涓瘝鍏冪殑缁撴潫浣嶇疆
private int endPosition;
/**
* Lucene 4.0 Tokenizer閫傞厤鍣ㄧ被鏋勯�犲嚱鏁�
* @param in
* @param useSmart
*/
public IKTokenizer(boolean useSmart) {
super();
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}
/*
* (non-Javadoc)
* @see org.apache.lucene.analysis.TokenStream#incrementToken()
*/
@Override
public boolean incrementToken() throws IOException {
// 娓呴櫎鎵�鏈夌殑璇嶅厓灞炴��
clearAttributes();
Lexeme nextLexeme = _IKImplement.next();
if (nextLexeme != null) {
// 灏哃exeme杞垚Attributes
// 璁剧疆璇嶅厓鏂囨湰
termAtt.append(nextLexeme.getLexemeText());
// 璁剧疆璇嶅厓闀垮害
termAtt.setLength(nextLexeme.getLength());
// 璁剧疆璇嶅厓浣嶇Щ
offsetAtt.setOffset(nextLexeme.getBeginPosition(), nextLexeme.getEndPosition());
// 璁板綍鍒嗚瘝鐨勬渶鍚庝綅缃�
endPosition = nextLexeme.getEndPosition();
// 璁板綍璇嶅厓鍒嗙被
typeAtt.setType(nextLexeme.getLexemeTypeString());
// 杩斾細true鍛婄煡杩樻湁涓嬩釜璇嶅厓
return true;
}
// 杩斾細false鍛婄煡璇嶅厓杈撳嚭瀹屾瘯
return false;
}
/*
* (non-Javadoc)
* @see org.apache.lucene.analysis.Tokenizer#reset(java.io.Reader)
*/
@Override
public void reset() throws IOException {
super.reset();
_IKImplement.reset(input);
}
@Override
public final void end() {
// set final offset
int finalOffset = correctOffset(this.endPosition);
offsetAtt.setOffset(finalOffset, finalOffset);
}
}
2.找到本地maven仓库中ikanalyzer-2012_u6.jar
复制到本地,删除jar包中ikanalyzer-2012_u6.jar\org\wltea\analyzer\lucene
的两个class文件:IKAnalyzer.class ,IKTokenizer.class
在本地代码的存放目录中找到项目中自己重写两个类的class文件(target目录),拷贝至
ikanalyzer-2012_u6.jar\org\wltea\analyzer\lucene
最后将jar包复制到solr\WEB-INF\lib目录下
solrhome\mycore\conf\managed-schema配置:
<!--定义动态类型-->
<dynamicField name="*_ik" type="text_ik" indexed="true" stored="true" />
<!--定义支持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>