lucene4.0版本号以后 已经用TokenStreamComponents 代替了TokenStream流。里面包含了filter和tokenizer

在较复杂的lucene搜索业务场景下,直接网上下载一个作为项目的分词器,是不够的。那么怎么去评定一个中文分词器的好与差:一般来讲。有两个点。词库和搜索效率,也就是算法。

 lucene的倒排列表中,不同的分词单元有不同的PositionIncrementAttribute,假设两个词之间PositionIncrementAttribute距离为0。则为同义词;比方:我定义美国和中国这两个词在倒排列表中是同一个位置及距离为0,那么搜索美国的话,中国也能出来。

这就是同义词搜索原理。

下面代码(用mmseg的 Tokenizer 去切词之后,然后再做同义词):

先自己定义分词器:

package hhc;

import java.io.Reader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import com.chenlb.mmseg4j.Dictionary;
import com.chenlb.mmseg4j.MaxWordSeg;
import com.chenlb.mmseg4j.analysis.MMSegTokenizer; /**
* 写一个分词器,一般能够參照原来分词器是怎么写法的
* @author hhc
*
*/
public class MySameAnalyzer extends Analyzer{
//同义词
private SamewordContext samewordContext=null; public MySameAnalyzer(SamewordContext samewordContext){
this.samewordContext=samewordContext;
} @Override
public TokenStream tokenStream(String fieldName, Reader reader) {
//
Dictionary dic=Dictionary.getInstance();
return new MySameTokenFilter(new MMSegTokenizer(new MaxWordSeg(dic), reader),samewordContext);
} }

然后再对TokenStream流做同义词处理

package hhc;

import java.io.IOException;
import java.util.Stack; import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.util.AttributeSource; public class MySameTokenFilter extends TokenFilter {
// 分词单元信息
private CharTermAttribute cta = null;
// 位置信息
private PositionIncrementAttribute pia = null;
// 状态
private AttributeSource.State current;
// 同义词集合
private Stack<String> sames = null;
private SamewordContext samewordContext=null; protected MySameTokenFilter(TokenStream input,SamewordContext samewordContext) {
super(input);
cta = input.addAttribute(CharTermAttribute.class);
pia = input.addAttribute(PositionIncrementAttribute.class);
sames=new Stack<String>();
this.samewordContext=samewordContext;
} @Override
public boolean incrementToken() throws IOException {
try {
if (sames!=null&&sames.size()> 0) {
// 删除对象在堆栈,然后返回的对象上的函数值。而且获取这个同义词
String str = sames.pop();
// 还原状态
restoreState(current);
cta.setEmpty();
cta.append(str);
pia.setPositionIncrement(0);
return true;
}
// 假设流中没有数据了。
if (!input.incrementToken())return false; /**
* 流中有数据的话,进行对应的同义词
*/
// 处理切分出来的词的信息
if (existAddSameword(cta.toString())) {
// 把当前状态先保存
current = captureState();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return true;
} /**
* 推断是否该分词单元存在
*
* @param word
* @return
*/
private boolean existAddSameword(String word) {
String[] words=samewordContext.getSameword(word);
if (words != null) {
for (String s : words) {
sames.push(s);
}
return true;
}
return false;
} }

最新文章

  1. PHP缓存技术
  2. Amazon AWS 架设EC2服务器(datizi)fanqiang (更新手机VPN/L2TP设置)
  3. 捉虫记(四)线程安全导致的HighCpu
  4. js模版引擎handlebars.js实用教程——循环中使用索引
  5. Android 如何解决数据库多线程锁的问题
  6. Python小爬虫-自动下载三亿文库文档
  7. Link-local address
  8. GWT用frame调用JSP
  9. 14.6.3.1 The InnoDB Buffer Pool
  10. ulimit开启coredump时核心转储
  11. 制作Orcad的变种BOM(Variant BOM)
  12. 用for while 成绩的有效输入
  13. CSS3学习笔记-1:CSS样式继承
  14. pip 安装问题
  15. SQL函数总结
  16. PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)
  17. is,as,类库
  18. CentOS 系统 git clone出错
  19. python3 设置滚动条
  20. python模块之time模块

热门文章

  1. Ubuntu16 远程连接MySQL
  2. 由Python通过__new__实现单例模式,所想到的__new__和__init__方法的区别
  3. 四:java调接口实现发送手机短信验证码功能
  4. shell全自动登录远程终端
  5. python之optparse模块
  6. Celery 源码解析八:State 和 Result
  7. sqlmap命令
  8. 优雅的使用Chrome调试Node程序
  9. input取值区间实例
  10. Nginx简介与安装