lucene全文检索概述(二)
目录
2.将IKAnalyzer2012_u6.jar手动添加到工程
一.lucene中的分词计算
全文检索中,分词重要性不言而喻,对于不同的语言环境,分词的逻辑也不同(英文文本和中文文本底层二进制编解码不一样,用中文分词逻辑分词英文,结果一定是错误的),lucene解决不同语言环境的分词逻辑;lucene提供了对外的分词器接口Analyzer;接口定义了实现规范;
全球范围内的各种团队,是Analyzer实现接口就能完成各自需要的分词器逻辑;
二.分词器代码
提供一个字符串,使用lucene已有的分词器进行分词计算,输出计算的词项打印,引用中文分词器IKAnalyzer实现分词计算余lucene提供的做个简单对比;了解IKAnalyzer使用配置.
1.创建一个maven的quickstart测试工程
2.添加依赖
1.引入需要的各种依赖
<dependency> <!-- 查询相关jar包 -->
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>6.0.0</version>
</dependency>
<dependency> <!-- lucene自带只能中文分词器jar包 -->
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-smartcn</artifactId>
<version>6.0.0</version>
</dependency>
<dependency> <!-- 测试用到的lucene工具包 -->
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>6.0.0</version>
</dependency>
<dependency> <!-- 测试用到的lucene核心包 -->
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>6.0.0</version>
</dependency>
版本6.0.0和其他配到软件一定要严格版本比对luke
2.依赖中提供的各种lucene已经实现的分词器
- SmartChineseAnalyzer:智能中文分词器
- WhitespaceAnalyzer:空格分词器
- SimpleAnalzyer:简单分词器,以标点符号为分词一句
- StandardAanalyzer:英文标准分词器.
3.测试代码
编辑一个调用的方法,将不同的分词器实现对象和解析的字符串传递过来,通过Analyzer接口的相关各种方法api将解析结果打印输出
1.字符串转化===转化为底层二进制
/**
* 测试各种分词器的分词结果
* @author TEDU
*
*/
public class AnalayzerTest {
public void printAnalyzer(Analyzer analyzer,String str) throws Exception{
//将字符串转化成字符串流
StringReader reader=new StringReader(str);
//将字符串流继续转化,转化成一个当前分词器底层计算结果的tocketStream
//每一个分词过程,都要对应一个域属性,做分词计算
TokenStream tokenStream = analyzer.tokenStream("test", reader);
//tokenStream中流就已经是计算结果的二进制了
tokenStream.reset();
//从头,获取流数据中的字符串属性
CharTermAttribute attribute =
tokenStream.getAttribute(CharTermAttribute.class);
while(tokenStream.incrementToken()){//获取tokenStream中分词的所有词项结果
System.out.println(attribute.toString());
}
}
2.功能测试
@Test
public void run() throws Exception{
//创建几个分词器的实现类
Analyzer a1=new SmartChineseAnalyzer();
Analyzer a2=new WhitespaceAnalyzer();
Analyzer a3=new SimpleAnalyzer();
Analyzer a4=new StandardAnalyzer();
Analyzer a5=new IKAnalyzer6x();
//计算的字符串内容
String msg="最新产品,不受中美贸易战影响的全新商品";
String msg1="德玛西亚,人在塔在!";
System.out.println("**********智能中文分词器**************");
printAnalyzer(a1, msg);
System.out.println("**********IK中文分词器**************");
printAnalyzer(a5, msg);
/*
System.out.println("**********空格分词器**************");
printAnalyzer(a2, msg);
System.out.println("**********简单分词器**************");
printAnalyzer(a3, msg);
System.out.println("**********标准分词器**************");
printAnalyzer(a4, msg);*/
}
}
4.测试结果
5.中文IK分词器
lucene中常用的一种中文分词器,
对于Lucene6.0以上的版本暂时没有对应版本的ik分词器,
以前的IK做一些简单调整;引入实现类IKAnalyzer6 IKTokenizer6
1.相关依赖
2.将IKAnalyzer2012_u6.jar手动添加到工程
3.实现类放到com.jt.lucene.IK;
相关代码工具包
public class IKTokenizer6x extends Tokenizer{
//ik分词器实现
private IKSegmenter _IKImplement;
//词元文本属性
private final CharTermAttribute termAtt;
//词元位移属性
private final OffsetAttribute offsetAtt;
//词元分类属性
private final TypeAttribute typeAtt;
//记录最后一个词元的结束位置
private int endPosition;
//构造函数,实现最新的Tokenizer
public IKTokenizer6x(boolean useSmart){
super();
offsetAtt=addAttribute(OffsetAttribute.class);
termAtt=addAttribute(CharTermAttribute.class);
typeAtt=addAttribute(TypeAttribute.class);
_IKImplement=new IKSegmenter(input, useSmart);
}
@Override
public final boolean incrementToken() throws IOException {
//清除所有的词元属性
clearAttributes();
Lexeme nextLexeme=_IKImplement.next();
if(nextLexeme!=null){
//将lexeme转成attributes
termAtt.append(nextLexeme.getLexemeText());
termAtt.setLength(nextLexeme.getLength());
offsetAtt.setOffset(nextLexeme.getBeginPosition(),
nextLexeme.getEndPosition());
//记录分词的最后位置
endPosition=nextLexeme.getEndPosition();
typeAtt.setType(nextLexeme.getLexemeText());
return true;//告知还有下个词元
}
return false;//告知词元输出完毕
}
@Override
public void reset() throws IOException {
super.reset();
_IKImplement.reset(input);
}
@Override
public final void end(){
int finalOffset = correctOffset(this.endPosition);
offsetAtt.setOffset(finalOffset, finalOffset);
}
}
package com.jt.lucene.IK;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
public class IKAnalyzer6x extends Analyzer{
private boolean useSmart;
public boolean useSmart(){
return useSmart;
}
public void setUseSmart(boolean useSmart){
this.useSmart=useSmart;
}
public IKAnalyzer6x(){
this(false);//IK分词器lucene analyzer接口实现类,默认细粒度切分算法
}
//重写最新版本createComponents;重载analyzer接口,构造分词组件
@Override
protected TokenStreamComponents createComponents(String filedName) {
Tokenizer _IKTokenizer=new IKTokenizer6x(this.useSmart);
return new TokenStreamComponents(_IKTokenizer);
}
public IKAnalyzer6x(boolean useSmart){
super();
this.useSmart=useSmart;
}
}
4.测试功能
6.分词器测试结论:
无论如何更新,也无法赶上时代的步伐,总是有过时的和为引入的分词结果,无法达到系统对全文检索分词计算的要求.
德玛西亚--{德玛}{西亚}{德玛西亚}
7.IK分词器配置扩展词典和停用词典
1.添加IK配置文件
当前ik分词器执行的classLoader范围内添加一个IK的配置文件和扩展停用词典文件即可
2.IKAnalyzer.cfg.xml:
IK分词器的配置文件
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典
<entry key="ext_dict">ext.dic;</entry>
-->
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_dict">ext.dic;</entry>
<entry key="ext_stopwords">stopword.dic;</entry>
</properties>
3.将这个文件放到classes里面
注意: 1 引用ext.dic扩展词典,和stopword.dic停用词典必须和配置文件xml同一个目录
2 扩展词典,停用词典在编辑中文时,要和当前工程的编解码格式一致,不能使用windows编辑器打开,eclipse打开去编辑内容
确保文件和项目使用的是同编码格式
4.项目编码,文件编码保持一致
5.设置eclipse格式
双击打开文件默认是Win的,设置为eclipse打开
6.编辑配置
7.运行测试
暂告一段落