lucene构建同义词分词器
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;
} }
lucene构建同义词分词器的更多相关文章
- 【Lucene3.6.2入门系列】第05节_自定义停用词分词器和同义词分词器
首先是用于显示分词信息的HelloCustomAnalyzer.java package com.jadyer.lucene; import java.io.IOException; import j ...
- Apache Lucene(全文检索引擎)—分词器
目录 返回目录:http://www.cnblogs.com/hanyinglong/p/5464604.html 本项目Demo已上传GitHub,欢迎大家fork下载学习:https://gith ...
- Lucene系列四:Lucene提供的分词器、IKAnalyze中文分词器集成、扩展 IKAnalyzer的停用词和新词
一.Lucene提供的分词器StandardAnalyzer和SmartChineseAnalyzer 1.新建一个测试Lucene提供的分词器的maven项目LuceneAnalyzer 2. 在p ...
- 【原创】Lucene.Net+盘古分词器(详细介绍)
本章阅读概要 1.Lucenne.Net简介 2.介绍盘古分词器 3.Lucene.Net实例分析 4.结束语(Demo下载) Lucene.Net简介 Lucene.net是Lucene的.net移 ...
- Lucene.Net+盘古分词器(详细介绍)(转)
出处:http://www.cnblogs.com/magicchaiy/archive/2013/06/07/LuceneNet%E7%9B%98%E5%8F%A4%E5%88%86%E8%AF%8 ...
- Lucene的中文分词器IKAnalyzer
分词器对英文的支持是非常好的. 一般分词经过的流程: 1)切分关键词 2)去除停用词 3)把英文单词转为小写 但是老外写的分词器对中文分词一般都是单字分词,分词的效果不好. 国人林良益写的IK Ana ...
- Lucene的中文分词器
1 什么是中文分词器 学过英文的都知道,英文是以单词为单位的,单词与单词之间以空格或者逗号句号隔开. 而中文的语义比较特殊,很难像英文那样,一个汉字一个汉字来划分. 所以需要一个能自动识别中文语义的分 ...
- 重写lucene.net的分词器支持3.0.3.0版本
lucene.net中每个分词器都是一个类,同时有一个辅助类,这个辅助类完成分词的大部分逻辑.分词类以Analyzer结尾,辅助类通常以Tokenizer结尾.分类词全部继承自Analyzer类,辅助 ...
- Lucene.Net+盘古分词器(详细介绍)
本章阅读概要1.Lucenne.Net简介2.介绍盘古分词器3.Lucene.Net实例分析4.结束语(Demo下载)Lucene.Net简介 Lucene.net是Lucene的.net移植版本,是 ...
随机推荐
- 【Kafka源码】ReplicaManager启动过程
在KafkaServer启动过程的入口中,会启动Replica Manager,众所周知,这是一个副本管理器.replica在Kafka中扮演的角色很重要,是保证消息不丢失的一个重要概念. repli ...
- TIBCO EMS安装部署
创建用户 groupadd -g 800 tibcouseradd -u 801 -g tibco -d /home/tibco/ -s /bin/bash tibco 目前关于sharedatast ...
- JavaScript系列----函数(Function)篇(4)
1.什么是函数? 在W3C中函数的定义是这么说的:函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. 诚然,从这种抽象的定义中我们得不到什么有价值的东西.下面,举例来列举出函数的几种定义 ...
- 15.javaweb XML详解教程
一.XML语言简介 1, 作用:用于描述和保存现实中具有某种关系的数据,还可以作为软件配置文件,和描述程序模块之间的关系 2, 语法: 首先 先看一个XML文件的组成部分 关于文档声明 Versi ...
- Java 核心内容相关面试题【4】
spingmvc 和 structs的区别 我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置. spring3 mvc可以认为已经100%零配置了(除了配置spring mv ...
- 使用cobbler批量安装操作系统(基于Centos7.x )
1.1 cobbler简介 Cobbler是一个Linux服务器安装的服务,可以通过网络启动(PXE)的方式来快速安装.重装物理服务器和虚拟机,同时还可以管理DHCP,DNS等. Cobbler可以使 ...
- .net core 在视图中快速获取路由(Areas、Controller、Action)
我们在.net core中,经常碰到需要获取当前的Areas.Controller.Action,于是小编就扩展了Html,这样即可使用 Html.***来获取这些信息. 具体扩展类如下: publi ...
- struts2的简单执行过程
struts2是最近刚学的一个框架,想通过写篇文章来加深下印象,这也是本篇博文产生的由来,下面进入正题 Struts2本身是一个挺简单的框架,我们通过写一个登陆的过程来具体描述下其执行过程 1.首先我 ...
- input取值区间实例
前端开发中经常会遇到 input 取值区间的需求,比如搜索的时候,价格区间,积分值区间 大致的需求为 input 的值必须是正整数,第二个 input 的值必须大于第一个 DOM结构如下: <d ...
- 十二、VueJs 填坑日记之项目打包发布
通过上一篇博文的学习,我们其实已经完成了我们设想的项目的开发.但是,我们做好的这套东西,是基于 nodejs 开发的.而我们最终希望,我们开发的项目,生成好一堆文件,然后随便通过任何一个 http 服 ...