Lucene分词原理与方式

--------------------------------------------------------
lucene的分词_分词器的原理讲解

--------------------------------------------------------

几个默认分词

SimpleAnalyzer
StopAnalyzer
WhitespaceAnalyzer(根据空格分词)

StandardAnalyzer

分词流程

Reader  ---->Tokenizer---->大量的TokenFilter---->最后生成TokenStream
Tokenizer:主要负责接收Reader字节流,将Reader进行分词操作。
TokenFilter:对已经分好词的语汇单元进行各种各样的过滤操作
TokenStream:分词器做好处理之后得到的一个流。这个流中存储了分词的各种信息,可以tokenStream有效的获取到分词单元信息


在这个流中分词需要存储的涉及的信息
CharTermAttribute:保存相应的词汇
OffsetAttribute:以增量的方式保存次序,各个词汇的偏移量
PositionIncrementAttribute:保存词与词之间的位置增量(0:同位词。2:表示中间有词汇)

TypeAttribute:类型信息


---------------------------------------------------------
lucene的分词_通过TokenStream显示分词
---------------------------------------------------------

/*
* 显示分词(TokenStream流再用CharTermAttribute捕获)
*/
public static void displayToken(String str, Analyzer a) {
	try {
		// "content"没有任何意义
		// 通过分词器Analyzer创建TokenStream流
		TokenStream stream = a.tokenStream("content", new StringReader(str));
		// 创建用于接收信息的CharTermAttribute,这个属性会添加到流中,随着TokenStream增加
		CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
		while (stream.incrementToken()) {
			System.out.print("[" + cta + "]");
		}
			System.out.println();
	} catch (IOException e) {
			e.printStackTrace();
	}
}
/*
*测试
*/
@Test
public void test01() {
	// 创建几个analyzer
	Analyzer a1 = new StandardAnalyzer(Version.LUCENE_35);
	Analyzer a2 = new StopAnalyzer(Version.LUCENE_35);
	Analyzer a3 = new SimpleAnalyzer(Version.LUCENE_35);
	Analyzer a4 = new WhitespaceAnalyzer(Version.LUCENE_35);


	String txt = "this is my house,I am come from HuNan";
	new AnalyzerUtils().displayToken(txt, a1);
	new AnalyzerUtils().displayToken(txt, a2);
	new AnalyzerUtils().displayToken(txt, a3);
	new AnalyzerUtils().displayToken(txt, a4);
}



-------------------------------------------------------------
lucene分词_通过TokenStream显示分词的详细信息
-------------------------------------------------------------

/*
 * 显示所有重要的分词信息
*/
public static void displayAllTokenInfo(String str, Analyzer a) {
	try {
	 TokenStream stream = a.tokenStream("content", new StringReader(str));
	// 增量信息
	PositionIncrementAttribute pia = stream.addAttribute(PositionIncrementAttribute.class);
	// offset偏移量信息OffsetAttribute oa = stream.addAttribute(OffsetAttribute.class);
	// 分词词汇信息
	CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
	// 类型信息
	TypeAttribute ta = stream.addAttribute(TypeAttribute.class);
	while (stream.incrementToken()) {
		System.out.print("位置增量" + pia.getPositionIncrement() + ":");
		System.out.print("词汇信息&偏移量&类型" + cta + "[" + oa.startOffset()+ "-" + oa.endOffset() + "]" + ta.type()+"\n");
                }
	} catch (Exception e) {
		e.printStackTrace();
	}
}


----------------------------------------------------------
lucene的分词_扩展stop分词(自定义stopfilterAnalyzer,增加过滤数组)
----------------------------------------------------------

/*
 * 自定义过滤分词器
 */
public class MystopAnalyzer extends Analyzer {
	private Set stops;


	public MystopAnalyzer(){
		stops=StopAnalyzer.ENGLISH_STOP_WORDS_SET;
	}
	public MystopAnalyzer(String[] sws) {
		// 查看默认过滤的词汇单元
		System.out.println(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
		// 创建分词器(会自动将字符串数组转化成set)
		stops = StopFilter.makeStopSet(Version.LUCENE_35, sws, true);
		// 给自定义的过滤分词器添加原来默认的过滤数组
		stops.addAll(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
	}


	@Override
	public TokenStream tokenStream(String fieldName, Reader reader) {
	// 添加过滤器链(filter)(过滤掉set数组,忽略大小写)和Tokenizer
		return new StopFilter(Version.LUCENE_35, 
		          new LowerCaseFilter(Version.LUCENE_35, 
		          new LetterTokenizer(Version.LUCENE_35,reader)), stops);
	}


}

//测试
// 创建自定义的analyzer(添加需要过滤掉的词汇单元	)
Analyzer a1 = new MystopAnalyzer(new String[]{"I","YOU"});


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。