`
linliangyi2007
  • 浏览: 1009798 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

发布IK Analyzer 3.0 中文分词器

阅读更多
最新:IKAnalyzer3.2.3稳定版已经发布,支持Lucene3.0和solr1.4
链接:http://www.iteye.com/topic/667095

lucene 2.9以前用户请使用 IKAnalyzer V3.1.6GAhttp://linliangyi2007.iteye.com/blog/512577

IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始, IKAnalyzer已经推出了3个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IK Analyzer 3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。

1.1 IK Analyzer 3.0结构设计


1.2 IK Analyzer 3.0特性
  • 采用了特有的“正向迭代最细粒度切分算法“,具有80万字/秒的高速处理能力
  • 采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。
  • 优化的词典存储,更小的内存占用。支持用户词典扩展定义
  • 针对Lucene全文检索优化的查询分析器IKQueryParser(作者吐血推荐);采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。


1.3 分词效果示例

文本原文1:
IK-Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始, IKAnalyzer已经推出了3个大版本。
分词结果:
ik-analyzer | 是 | 一个 | 一 | 个 | 开源 | 的 | 基于 | java | 语言 | 开发 |  的 | 轻量级 | 量级 | 的 | 中文 | 分词 | 工具包 | 工具 |  从  | 2006 | 年 | 12 | 月 | 推出 | 1.0  | 版 | 开始 | ikanalyzer | 已经 |  推出 | 出了 |  3  |  个大 |  个 | 版本

文本原文2:
永和服装饰品有限公司
分词结果:
永和 | 和服 | 服装 | 装饰品 | 装饰 | 饰品 | 有限 |  公司

文本原文3:
作者博客:linliangyi2007.iteye.com   电子邮件:linliangyi2005@gmail.com
分词结果:
作者 | 博客 |  linliangyi2007.iteye.com |  2007 |  电子邮件 |  电子 |  邮件 |  地址 |  linliangyi2005@gmail.com |  2005

2.使用指南

2.1下载地址
GoogleCode开源项目 :http://code.google.com/p/ik-analyzer/
GoogleCode SVN下载:http://ik-analyzer.googlecode.com/svn/trunk/

2.2安装部署
IK Analyzer安装包包含:
1. 《IKAnalyzer中文分词器V3.0使用手册》(即本文档)
2. IKAnalyzer3.0GA.jar
3. IKAnalyzer.cfg.xml
它的安装部署十分简单,将IKAnalyzer3.0GA.jar部署于项目的lib目录中;IKAnalyzer.cfg.xml文件放置在代码根目录(对于web项目,通常是WEB-INF/classes目录,同hibernate、log4j等配置文件相同)下即可。


2.3 Lucene用户快速入门

代码样例
/**
 * IK Analyzer Demo
 * @param args
 */
import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
//引用IKAnalyzer3.0的类
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

/**
 * @author linly
 *
 */
public class IKAnalyzerDemo {
	
	public static void main(String[] args){
		//Lucene Document的域名
		String fieldName = "text";
		 //检索内容
		String text = "IK Analyzer是一个结合词典分词和文法分词的中文分词开源工具包。它使用了全新的正向迭代最细粒度切分算法。";
		
		//实例化IKAnalyzer分词器
		Analyzer analyzer = new IKAnalyzer();
	 
		
		Directory directory = null;
		IndexWriter iwriter = null;
		IndexSearcher isearcher = null;
		try {
			//建立内存索引对象
			directory = new RAMDirectory();	 
			iwriter = new IndexWriter(directory, analyzer, true , IndexWriter.MaxFieldLength.LIMITED);
			Document doc = new Document();
			doc.add(new Field(fieldName, text, Field.Store.YES, Field.Index.ANALYZED));
			iwriter.addDocument(doc);
			iwriter.close();
			
		    //实例化搜索器   
			isearcher = new IndexSearcher(directory);			
			//在索引器中使用IKSimilarity相似度评估器
			isearcher.setSimilarity(new IKSimilarity());
			
			String keyword = "中文分词工具包";
			
			//使用IKQueryParser查询分析器构造Query对象
			Query query = IKQueryParser.parse(fieldName, keyword);
			
			//搜索相似度最高的5条记录
			TopDocs topDocs = isearcher.search(query , 5);
			System.out.println("命中:" + topDocs.totalHits);
			//输出结果
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			for (int i = 0; i < topDocs.totalHits; i++){
				Document targetDoc = isearcher.doc(scoreDocs[i].doc);
				System.out.println("内容:" + targetDoc.toString());
			}			
			
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if(isearcher != null){
				try {
					isearcher.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(directory != null){
				try {
					directory.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

执行结果:
命中:1
内容:Document<stored/uncompressed,indexed,tokenized<text:IK Analyzer是一个结合词典分词和文法分词的中文分词开源工具包。它使用了全新的正向迭代最细粒度切分算法。>>



2.4 关键API说明

 类org.wltea.analyzer.lucene.IKAnalyzer
说明:IK分词器的主类,是IK分词器的Lucene Analyzer类实现。
该类使用方法请参考 “代码样例”章节

 类org.wltea.analyzer.lucene.IKQueryParser
 public static Query parse(String field , String query) throws IOException
说明:单条件,单Field查询分析
参数1 :String field,  查询的目标域名称
参数2 :String query , 查询的关键字
返回值:构造一个单条件,单Field查询器

 public static Query parseMultiField(String[] fields , String query) throws IOException
说明:多Field,单条件查询分析
参数1 :String[] fields,  多个查询的目标域名称的数组
参数2 :String query , 查询的关键字
返回值:构造一个多Field,单条件的查询器

 public static Query parseMultiField(String[] fields , String query ,  BooleanClause.Occur[] flags) throws IOException
说明:多Field,单条件,多Occur查询分析
参数1 :String[] fields,  多个查询的目标域名称的数组
参数2 :String query , 查询的关键字
参数3 :BooleanClause.Occur[] flags , 查询条件的组合方式(Or/And)
返回值:构造一个多Field,单条件,多Occur的查询器

 public static Query parseMultiField(String[] fields , String[] queries) throws IOException
说明:多Field,多条件查询分析
参数1 :String[] fields,  多个查询的目标域名称的数组
参数2 :String[] queries , 对应多个查询域的关键字数组
返回值:构造一个多Field,多条件的查询器

 public static Query parseMultiField(String[] fields , String[] queries , BooleanClause.Occur[] flags) throws IOException
说明:多Field,多条件,多Occur查询
参数1 :String[] fields,  多个查询的目标域名称的数组
参数2 :String[] queries , 对应多个查询域的关键字数组
参数3 :BooleanClause.Occur[] flags , 查询条件的组合方式(Or/And)
返回值:构造一个多Field, 多条件, 多Occur的查询器

 类org.wltea.analyzer.lucene.IKSimilarity
说明: IKAnalyzer 的相似度评估器。该类重载了DefaultSimilarity的coord方法,提高词元命中个数在相似度比较中的权重影响,即,当有多个词元得到匹配时,文档的相似度将提高。
该类使用方法请参考 “代码样例”章节

 类org.wltea.analyzer.IKSegmentation
说明: 这是IK分词器的核心类。它是真正意义上的分词器实现。IKAnalyzer的3.0版本有别于之前的版本,它是一个可以独立于Lucene的Java分词器实现。当您需要在Lucene以外的环境中单独使用IK中文分词 组件时,IKSegmentation正是您要找的。
 public Lexeme next() throws IOException
说明:读取分词器切分出的下一个语义单元,如果返回null,表示分词器已经结束。
返回值:Lexeme 语义单元对象,即相当于Lucene的词元对象Token

 类org.wltea.analyzer.Lexeme
说明: 这是IK分词器的语义单元对象,相当于Lucene中的Token词元对象。由于3.0版本被设计为独立于Lucene的Java分词器实现,因此它需要Lexeme来代表分词的结果。
 public int getBeginPosition()
说明:获取语义单元的起始字符在文本中的位置
返回值:int , 语义单元相对于文本的绝对起始位置

 public int getEndPosition()
说明:获取语义单元的结束字符的下一个位置
返回值:int , 语义单元相对于文本的绝对终止位置的下一个字符位置

 public int getLength()
说明:获取语义单元包含字符串的长度
返回值:int , 语义单元长度 = getEndPosition – getBeginPosition

 public String getLexemeText()
说明:获取语义单元包含字符串内容
返回值:String, 语义单元的实际内容,即分词的结果


3.词表扩展

目前,IK分词器自带的主词典拥有22万左右的汉语单词量。由于作者个人的精力有限,并没有对搜集到的词库进行全范围的筛选、清理。此外,对于分词组件应用场景所涉及的领域的不同,也需要各类专业词库的支持。为此,IK分词器提供了对词典的扩充支持。

基于API的词典扩充
IK分词器支持使用API编程模型扩充您的词典。如果您的词典是存储与数据库中,这个方式应该对您适用。API如下:

 类org.wltea.analyzer.dic.Dictionary
说明: IK分词器的词典对象。它负责中文词汇的加载,内存管理和匹配检索。
 public static void loadExtendWords(List<String> extWords)
说明:加载用户扩展的词汇列表到IK的主词典中,增加分词器的可识别词语。
参数1:List<String> extWords , 扩展的词汇列表
返回值:无

3.2基于配置的词典扩充
IK分词器还支持通过配置IKAnalyzer.cfg.xml文件来扩充您的专有词典。

1. 部署IKAnalyzer.cfg.xml
IKAnalyzer.cfg.xml部署在代码根目录下(对于web项目,通常是WEB-INF/classes目录)同hibernate、log4j等配置文件相同。

2. 词典文件的编辑与部署
分词器的词典文件格式是无BOM的UTF-8编码的中文文本文件,文件扩展名不限。词典中,每个中文词汇独立占一行,使用\r\n的DOS方式换行。(注,如果您不了解什么是无BOM的UTF-8格式, 请保证您的词典使用UTF-8存储,并在文件的头部添加一空行)。您可以参考分词器源码org.wltea.analyzer.dic包下的.dic文件。

词典文件应部署在Java的资源路径下,即ClassLoader能够加载的路径中。(推荐同IKAnalyzer.cfg.xml放在一起)


3. IKAnalyzer.cfg.xml文件的配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典-->
	<entry key="ext_dict">/mydict.dic ; /mypack/mydict2.dic ; /com/mycompany/dic/mydict3.dic ;</entry> 
</properties>

在配置文件中,用户可一次配置多个词典文件。文件名使用“;”号分隔。文件路径为相对java包的起始根路径。

(全文终)


下载 :IKAnalyzer3.1.1稳定版完整包.rar

更多详细请参看《IKAnalyzer中文分词器V3.1.1使用手册.pdf》








分享到:
评论
116 楼 kexzcle 2010-02-09  
请问,IK词典的配置问题,IKAnalyzer.cfg.xml 放在哪里都无所谓是么?

里面配置 /ext_stopwords.dic

那IKAnalyzer.cfg.xml 放在src/ 

同样ext_stopwords.dic 也放到src/ 下..我试了下没有作用呢,停止词! 是否配置错误?
115 楼 linliangyi2007 2010-01-28  
firesnake2008 写道
linliangyi2007 写道
firesnake2008 写道
来 吧,也用了这个分词
感觉效果还不错,可以自己用了自定义词库。这个比较好

哪个“来吧”?

晕,不是这个意思,是中间有词屏蔽。。帖子没打印出来,呵呵

我想请教LZ,分词以后的词还是太多了,如果作为关键字送出去太多了,想再屏蔽部分词语,但没有其他库或更多文字。不能来选择权重之类的。

有很弱的想法。。。能否把这些词再去和默认的词库里的词比较啊,比如人名库,地名库。找到了有这个词那就留下,没有就扔了

这样能实现么?咋和词库的词比较呢。


你的做法是可以的,在IK中有个Dictionary的字典工具类,里面有对主词典进行匹配的方法,详细可以参考IK的Java DOC文档
114 楼 firesnake2008 2010-01-27  
linliangyi2007 写道
firesnake2008 写道
来 吧,也用了这个分词
感觉效果还不错,可以自己用了自定义词库。这个比较好

哪个“来吧”?

晕,不是这个意思,是中间有词屏蔽。。帖子没打印出来,呵呵

我想请教LZ,分词以后的词还是太多了,如果作为关键字送出去太多了,想再屏蔽部分词语,但没有其他库或更多文字。不能来选择权重之类的。

有很弱的想法。。。能否把这些词再去和默认的词库里的词比较啊,比如人名库,地名库。找到了有这个词那就留下,没有就扔了

这样能实现么?咋和词库的词比较呢。
113 楼 linliangyi2007 2010-01-27  
firesnake2008 写道
来 吧,也用了这个分词
感觉效果还不错,可以自己用了自定义词库。这个比较好

哪个“来吧”?
112 楼 firesnake2008 2010-01-27  
来 吧,也用了这个分词
感觉效果还不错,可以自己用了自定义词库。这个比较好
111 楼 linliangyi2007 2010-01-13  
swprogrammer 写道
用户输入关键字  然后在索引中去搜索,不具体根据数据库哪个字段的索引去搜索,而我建立的索引是根据数据库每个字段去建立的
我就是要做这样的搜索


Lucene的搜索就是针对文档的所有有index标识的field的。但你取结果的时候,怎么取就看你的程序了。
110 楼 swprogrammer 2010-01-13  
用户输入关键字  然后在索引中去搜索,不具体根据数据库哪个字段的索引去搜索,而我建立的索引是根据数据库每个字段去建立的
我就是要做这样的搜索
109 楼 linliangyi2007 2010-01-12  
swprogrammer 写道
package lucene.database;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

public class LuceneDemo {

	// 索引存放目录
	private String directory = "d:/index/";
	
	//根据哪个字段去查询
	public String searchField = "";
	
	//搜索相似度最高的几条记录
	public int n = 5;
	
	public LuceneDemo(String searchField, int n)
	{
		this.searchField = searchField;
		this.n = n;
	}

	/**
	 * 查询数据并创建索引
	 * 
	 * @param rs
	 *            数据集
	 */
	public void Index(ResultSet rs) {
		try {
			IndexWriter writer = new IndexWriter(directory, getAnalyzer(), true);
			int mergeFactor = 1000;
			int maxMergeDocs = Integer.MAX_VALUE; 
			writer.setMergeFactor(mergeFactor);
			writer.setMaxMergeDocs(maxMergeDocs);

			while (rs.next()) {
				Document doc = new Document();
				doc.add(new Field("id", rs.getString("au_id"), Field.Store.YES,
						Field.Index.ANALYZED));
				doc.add(new Field("name", rs.getString("au_name"),
						Field.Store.YES, Field.Index.ANALYZED));
				doc.add(new Field("phone", rs.getString("phone"),
						Field.Store.YES, Field.Index.ANALYZED));
				doc.add(new Field("address", rs.getString("address"),
						Field.Store.YES, Field.Index.ANALYZED));
				doc.add(new Field("City", rs.getString("city"),
						Field.Store.YES, Field.Index.ANALYZED));
				writer.addDocument(doc);
			}
			writer.optimize();
			writer.close();
		} catch (IOException e) {
			System.out.println(e);
		} catch (SQLException e) {
			System.out.println(e);
		}
	}

	public TopDocs seacher(String queryString) {
		TopDocs topDocs = null;
		try {
			
			//使用IKQueryParser查询分析器构造Query对象
			Query query = IKQueryParser.parse("city", queryString);
			if(searchField != null && !"".equals(searchField))
			{
				query = IKQueryParser.parse("city", queryString);
			}else
			{
				query = IKQueryParser.parseMultiField(new String[]{"id","name","phone","address","City"}, queryString);
			}
			
			//搜索相似度最高的5条记录
			topDocs = getIndexSearcher().search(query , n);
		} catch (Exception e) {
			System.out.print(e);
		}
		return topDocs;
	}

	/**
	 * 获取分词器
	 * 
	 * @return 分词器
	 */
	public Analyzer getAnalyzer() {
		// 创建中文分词器并返回
		return new IKAnalyzer();
	}
	
	/**
	 * 获取搜索器
	 * @return 搜索器
	 * @throws CorruptIndexException
	 * @throws IOException
	 */
	public IndexSearcher getIndexSearcher() throws CorruptIndexException, IOException
	{
		//实例化搜索器   
		IndexSearcher isearcher = new IndexSearcher(directory);			
		//在索引器中使用IKSimilarity相似度评估器
		isearcher.setSimilarity(new IKSimilarity());
		return isearcher;
	}
}


package lucene.database;

import java.io.IOException;
import java.util.Date;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

public class Test {

	public static void main(String[] args) throws CorruptIndexException, IOException {

		DatabaseLuceneDemo dld = new DatabaseLuceneDemo();
		Date start = new Date();
		LuceneDemo luceneDemo = new LuceneDemo("", 5);
		luceneDemo.Index(dld.query("select * from Authors"));

		TopDocs topDocs = luceneDemo.seacher("023");

		Date end = new Date();
		System.out.println(end.getTime() - start.getTime());
		System.out.println("命中:" + topDocs.totalHits);
		//结果
		ScoreDoc[] scoreDocs = topDocs.scoreDocs;
		
		//获取查询分析器
		IndexSearcher isearcher = luceneDemo.getIndexSearcher();
		
		for (int i = 0; i < topDocs.totalHits; i++){
			Document targetDoc = isearcher.doc(scoreDocs[i].doc);
			//targetDoc.getField("id").setValue("fdafdf");
			System.out.println("内容:" + targetDoc.get("id") + " " + targetDoc.get("name") + " " + targetDoc.get("phone")
					 + " " + targetDoc.get("address") + " " + targetDoc.get("City"));
		}
	}
	
}



结果:
2172
命中:996
内容:1 周海诺 023-88888888 11111 aaaa
内容:3 彭珊珊 023-88833338 3333 cccc
内容:4 刘敏 023-88899999 4444 dddd
内容:9 999 023-99999999 9999 99999
内容:9 999 023-99999999 9999 99999
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	at lucene.database.Test.main(Test.java:33)



  这里还有个下标越界错误,这个我能搞懂, 但这个冗余是能过滤吗?怎么过滤?


哥哥,这个就是你取索引的方法有问题了啊。我不是很清楚你对结果的查询要求,所以没法给你完整的建议。但从分词器的角度上说,它已经圆满完成任务了。
108 楼 swprogrammer 2010-01-12  
package lucene.database;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

public class LuceneDemo {

	// 索引存放目录
	private String directory = "d:/index/";
	
	//根据哪个字段去查询
	public String searchField = "";
	
	//搜索相似度最高的几条记录
	public int n = 5;
	
	public LuceneDemo(String searchField, int n)
	{
		this.searchField = searchField;
		this.n = n;
	}

	/**
	 * 查询数据并创建索引
	 * 
	 * @param rs
	 *            数据集
	 */
	public void Index(ResultSet rs) {
		try {
			IndexWriter writer = new IndexWriter(directory, getAnalyzer(), true);
			int mergeFactor = 1000;
			int maxMergeDocs = Integer.MAX_VALUE; 
			writer.setMergeFactor(mergeFactor);
			writer.setMaxMergeDocs(maxMergeDocs);

			while (rs.next()) {
				Document doc = new Document();
				doc.add(new Field("id", rs.getString("au_id"), Field.Store.YES,
						Field.Index.ANALYZED));
				doc.add(new Field("name", rs.getString("au_name"),
						Field.Store.YES, Field.Index.ANALYZED));
				doc.add(new Field("phone", rs.getString("phone"),
						Field.Store.YES, Field.Index.ANALYZED));
				doc.add(new Field("address", rs.getString("address"),
						Field.Store.YES, Field.Index.ANALYZED));
				doc.add(new Field("City", rs.getString("city"),
						Field.Store.YES, Field.Index.ANALYZED));
				writer.addDocument(doc);
			}
			writer.optimize();
			writer.close();
		} catch (IOException e) {
			System.out.println(e);
		} catch (SQLException e) {
			System.out.println(e);
		}
	}

	public TopDocs seacher(String queryString) {
		TopDocs topDocs = null;
		try {
			
			//使用IKQueryParser查询分析器构造Query对象
			Query query = IKQueryParser.parse("city", queryString);
			if(searchField != null && !"".equals(searchField))
			{
				query = IKQueryParser.parse("city", queryString);
			}else
			{
				query = IKQueryParser.parseMultiField(new String[]{"id","name","phone","address","City"}, queryString);
			}
			
			//搜索相似度最高的5条记录
			topDocs = getIndexSearcher().search(query , n);
		} catch (Exception e) {
			System.out.print(e);
		}
		return topDocs;
	}

	/**
	 * 获取分词器
	 * 
	 * @return 分词器
	 */
	public Analyzer getAnalyzer() {
		// 创建中文分词器并返回
		return new IKAnalyzer();
	}
	
	/**
	 * 获取搜索器
	 * @return 搜索器
	 * @throws CorruptIndexException
	 * @throws IOException
	 */
	public IndexSearcher getIndexSearcher() throws CorruptIndexException, IOException
	{
		//实例化搜索器   
		IndexSearcher isearcher = new IndexSearcher(directory);			
		//在索引器中使用IKSimilarity相似度评估器
		isearcher.setSimilarity(new IKSimilarity());
		return isearcher;
	}
}


package lucene.database;

import java.io.IOException;
import java.util.Date;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;

public class Test {

	public static void main(String[] args) throws CorruptIndexException, IOException {

		DatabaseLuceneDemo dld = new DatabaseLuceneDemo();
		Date start = new Date();
		LuceneDemo luceneDemo = new LuceneDemo("", 5);
		luceneDemo.Index(dld.query("select * from Authors"));

		TopDocs topDocs = luceneDemo.seacher("023");

		Date end = new Date();
		System.out.println(end.getTime() - start.getTime());
		System.out.println("命中:" + topDocs.totalHits);
		//结果
		ScoreDoc[] scoreDocs = topDocs.scoreDocs;
		
		//获取查询分析器
		IndexSearcher isearcher = luceneDemo.getIndexSearcher();
		
		for (int i = 0; i < topDocs.totalHits; i++){
			Document targetDoc = isearcher.doc(scoreDocs[i].doc);
			//targetDoc.getField("id").setValue("fdafdf");
			System.out.println("内容:" + targetDoc.get("id") + " " + targetDoc.get("name") + " " + targetDoc.get("phone")
					 + " " + targetDoc.get("address") + " " + targetDoc.get("City"));
		}
	}
	
}



结果:
2172
命中:996
内容:1 周海诺 023-88888888 11111 aaaa
内容:3 彭珊珊 023-88833338 3333 cccc
内容:4 刘敏 023-88899999 4444 dddd
内容:9 999 023-99999999 9999 99999
内容:9 999 023-99999999 9999 99999
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	at lucene.database.Test.main(Test.java:33)



  这里还有个下标越界错误,这个我能搞懂, 但这个冗余是能过滤吗?怎么过滤?
107 楼 linliangyi2007 2010-01-11  
swprogrammer 写道
楼主,我想问下,对于数据冗余是怎么处理的?

例如:
我对数据库一张表的每个字段都建立了索引,但我搜索的时候,不想针对一个字段就行搜索,是在所有字段中搜索,
这样搜索出来的结果就会出现冗余,数据库一条记录可能会被搜索到多次

我想问的是,有什么办法能过滤这些冗余的数据

例如:
在检搜索引1中搜索到了数据2(索引1中存在数据2中一个字段的索引),那么在检搜索引2的时候就过滤掉数据2(索引2中存在数据2中一个字段的索引),不对数据2进行搜索


你说的是数据库中才会有这个问题的,Lucene本身就是全文搜索(全字段搜索)的,不会出现结果重复。
106 楼 swprogrammer 2010-01-11  
楼主,我想问下,对于数据冗余是怎么处理的?

例如:
我对数据库一张表的每个字段都建立了索引,但我搜索的时候,不想针对一个字段就行搜索,是在所有字段中搜索,
这样搜索出来的结果就会出现冗余,数据库一条记录可能会被搜索到多次

我想问的是,有什么办法能过滤这些冗余的数据

例如:
在检搜索引1中搜索到了数据2(索引1中存在数据2中一个字段的索引),那么在检搜索引2的时候就过滤掉数据2(索引2中存在数据2中一个字段的索引),不对数据2进行搜索
105 楼 linliangyi2007 2010-01-06  
Rexwong 写道
linliangyi2007 写道
Rexwong 写道
细粒度分词,很是钦佩。能有最新的源代码吗?


有啊,开源当然有源码啊。google code地址上去就有了,可以使用svn,也有打包好的。

晕了,在你的blog里下了个rar,没有源码,就没去code Google看看。懒了,懒了
另外,请教一下,在“神话电视连续剧”搜“神话电视”没有搜到。“神话电视”应该是切成“神话”“电视”了。导致这个结果是个什么原因呢?


有一种可能,你的Analyzer设置成最大切分模式,“神话电视连续剧”可能被切分为
神话电视连续剧
0-2 : 神话 : 	CJK_NORMAL
2-7 : 电视连续剧 : 	CJK_NORMAL

这样你使用“神话“and”电视”搜索就搜不到,请使用IKAnalyzer默认的构造函数,或者IKAnalyzer(false),这样的切分结果是
神话电视连续剧
0-2 : 神话 : 	CJK_NORMAL
2-7 : 电视连续剧 : 	CJK_NORMAL
2-4 : 电视 : 	CJK_NORMAL
4-7 : 连续剧 : 	CJK_NORMAL
4-6 : 连续 : 	CJK_NORMAL

104 楼 Rexwong 2010-01-06  
linliangyi2007 写道
Rexwong 写道
细粒度分词,很是钦佩。能有最新的源代码吗?


有啊,开源当然有源码啊。google code地址上去就有了,可以使用svn,也有打包好的。

晕了,在你的blog里下了个rar,没有源码,就没去code Google看看。懒了,懒了
另外,请教一下,在“神话电视连续剧”搜“神话电视”没有搜到。“神话电视”应该是切成“神话”“电视”了。导致这个结果是个什么原因呢?
103 楼 linliangyi2007 2010-01-06  
fuwang 写道
linliangyi2007 写道
引用
请教一个问题,比如我对一个字符串 "硬盘驱动器" 做索引了以后, 搜索 "硬" 或者 "盘" 都不能搜索到,但是如果搜索"硬盘"就可以,这是什么问题呢?


lucene是按照分词切分的结果进行完整匹配查询的, "硬盘驱动器"被切分成“硬盘”“驱动”“驱动器”,但没有“硬" 和 "盘",(那样是单字切分),因此搜索不到,这个是lucene的基础概念,切记。


要是今年多了一个新词叫“盘驱”,明年多了一个新词叫“动器”,怎么办?
如果客户强烈要求搜“硬”时能搜到记录,怎么办?


我觉得你这个需求是为杜撰而杜撰的,首先就与中文的特性违背了。每种语言都有它的切分特性,英文是通过空格分隔,而中文的特性我们采用了词库。这就意味着当“硬盘”是一个词语的时候,“硬”与“硬盘”在词义上是毫无关系的。分词器只可能尽可能适应于中文的常规语法切分,而不可能你想怎么分就怎么分。

lucene索引的特性也决定了它的最高效率是“完全索引匹配”,当然你可以使用“前缀匹配”,但这个与lucene的倒排索引设计理念是背道而驰的。
102 楼 fuwang 2010-01-06  
linliangyi2007 写道
引用
请教一个问题,比如我对一个字符串 "硬盘驱动器" 做索引了以后, 搜索 "硬" 或者 "盘" 都不能搜索到,但是如果搜索"硬盘"就可以,这是什么问题呢?


lucene是按照分词切分的结果进行完整匹配查询的, "硬盘驱动器"被切分成“硬盘”“驱动”“驱动器”,但没有“硬" 和 "盘",(那样是单字切分),因此搜索不到,这个是lucene的基础概念,切记。


要是今年多了一个新词叫“盘驱”,明年多了一个新词叫“动器”,怎么办?
如果客户强烈要求搜“硬”时能搜到记录,怎么办?
101 楼 linliangyi2007 2010-01-05  
Rexwong 写道
细粒度分词,很是钦佩。能有最新的源代码吗?


有啊,开源当然有源码啊。google code地址上去就有了,可以使用svn,也有打包好的。
100 楼 Rexwong 2010-01-05  
细粒度分词,很是钦佩。能有最新的源代码吗?
99 楼 linliangyi2007 2009-12-23  
你可以是用IK Analyzer 3.2.0stable 对 Lucene2.9以上版本
98 楼 swprogrammer 2009-12-23  
谢了,楼主,lucene版本问题,我开始用的2.2的,换个2.9的就行了

我还问下,lucene和IKAnalyzer的版本太多了,到底 他们的哪个版本最好,稳定些
97 楼 linliangyi2007 2009-12-23  
引用

怎么不行啊,楼主

IndexWriter.MaxFieldLength.LIMITED  , Field.Index.ANALYZED 和 isearcher.search(query , 5); 报错啊


我将IKAnalyzer3.0GA.jar部署于项目的lib目录中;IKAnalyzer.cfg.xml放到了src根下

为什么?


首先你用的是什么版本的Lucene,其次,IKAnalyzer的版本是多少?IK for lucene2.x的最新版是3.1.6GA,for Lucene3.0的是3.2statble

相关推荐

    Lucene的IK Analyzer 3.0 中文分词器 全解

    - 安装过程简单,只需将IKAnalyzer3.0GA.jar添加到项目的lib目录,配置文件IKAnalyzer.cfg.xml则应放在代码根目录或WEB-INF/classes目录下。 - 对于Lucene用户,可以快速入门通过Java代码示例进行索引和查询操作,...

    IKAnalyzer 3.0 中文分词器

    新版本的IKAnalyzer3.0 则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。 1.2IKAnalyzer3.0特性 * 采用了特有的“正向迭代最细粒度切分算法“,具有50万字/秒的高速处理...

    IKAnalyzer3.0

    总的来说,IKAnalyzer3.0作为一个成熟的中文分词工具,不仅提供了高效的分词性能,还考虑到了实际应用中的灵活性和可扩展性,是Java开发人员处理中文文本的理想选择。通过阅读提供的文档和手册,开发者可以更好地...

    IKAnalyzer 中文分词 完整java项目demo

    IKAnalyzer非常易用的java分词工具。可以自定义扩展词汇。 这个是一个完整的java项目demo。直接可以用,不用再去google下载了。添加了几个自定义词汇,测试好用。 运行ika.java里的main方法即可

    使用IK Analyzer实现中文分词之Java实现

    从 2006年 12 月推出 1.0 版开始, IKAnalyzer 已经推出了 4 个大版本。最初,它是以开源项目Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。 从 3.0 版本开始,IK 发展为面向 Java 的公用分词...

    java IKAnalyzer 中文分词器

    首先,你需要将压缩包中的`IKAnalyzer3.0GA.jar`文件添加到你的项目库目录(通常是`lib`目录)。这个JAR文件包含了IKAnalyzer的核心分词算法和相关实现,确保项目运行时可以找到并加载这些类。如果你的项目是Maven...

    IKAnalyzer中文分词器

    1. **正向迭代最细粒度切分算法**:IKAnalyzer3.0采用了这一独特算法,能够以每秒60万字的速度进行高效处理,显著提高了分词效率。 2. **多子处理器分析模式**:支持包括英文字母、IP地址、Email、URL、数字(如日期...

    IKAnalyzer中文分词器v2012使用手册.pdf

    IKAnalyzer是一款开源的基于Java语言开发的轻量级中文分词工具包,最早版本于2006年12月发布。作为一个文本分析组件,它最初是作为开源项目Lucene的一部分,综合运用了词典分词和文法分析算法。IKAnalyzer从3.0版本...

    IKAnalyzer3.1.2GA_AllInOne

    新版本的IKAnalyzer3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。 IKAnalyzer3.0特性: 采用了特有的“正向迭代最细粒度切分算法“,具有50万字/秒的高速处理能力。 ...

    IKAnalyzer中文分词器V2012使用手册_20190806.pdf

    这个分词器最初是基于开源项目Lucene的词典分词和文法分析算法开发的,但到了3.0版本之后,IKAnalyzer发展成为了一个独立于Lucene的通用分词组件,并提供了对Lucene的默认优化实现。 IKAnalyzer2012的结构设计采用...

    IKAnalyzer中文分词器 3.2.0 源码包.rar

    新版本的IKAnalyzer3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。 IKAnalyzer3.0特性: 采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力...

    IKAnalyzer中文分词好帮手

    #### 一、IKAnalyzer3.0介绍 IKAnalyzer是一款基于Java语言开发的开源中文分词工具包。自2006年12月首次发布以来,它已经经历了三个主要版本的发展。最初,它是为Lucene项目定制的中文分词组件,结合了词典分词和...

    IK Analyzer 开源中文分词 2012 u6.zip

    从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于...

    IKAnalyzer中文分词器 v3.2 使用手册.rar

    新版本的IKAnalyzer3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。 IKAnalyzer3.0特性: 采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力。...

    IKAnalyzer中文分词器V3.1.1使用手册

    IKAnalyzer3.0介绍 **IKAnalyzer**是一款基于Java语言编写的轻量级中文分词工具包,自2006年发布1.0版以来,已经经历了多个大版本的迭代。最初作为开源项目Lucene的一部分,它主要服务于该搜索引擎框架,通过结合...

    \IKAnalyzer中文分词器V3.1.3使用手册.pdf

    IKAnalyzer3.0介绍 IKAnalyzer是一款专为中文文本处理设计的高性能分词工具包,自2006年首次发布以来,已历经多次迭代升级至V3.1.3版本。最初作为Lucene项目的一部分,IKAnalyzer现已发展成为独立的Java分词组件,...

    IKAnalyzer开源轻量级中文分词工具包2012u6

    从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于...

    IKAnalyzer中文分词器V3.2.0使用手册

    ### IKAnalyzer中文分词器V3.2.0使用手册:关键知识点解析 #### 1. IKAnalyzer3.X概述 IKAnalyzer是一款专为中文环境设计的高性能、轻量级的分词工具包,由Java语言编写,自2006年12月发布1.0版以来,已历经多次...

    IKAnalyzer3.1.6GA完整包

    年12 月推出1.0 版开始, IKAnalyzer 已经推出了3 个大版本。最初,它是以开源项目 Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IK Analyzer 3.0 则发展为面向Java 的公用分词组件,...

Global site tag (gtag.js) - Google Analytics