Lucene开发手册

上传人:xian****hua 文档编号:157129557 上传时间:2022-09-28 格式:DOC 页数:46 大小:216.52KB
收藏 版权申诉 举报 下载
Lucene开发手册_第1页
第1页 / 共46页
Lucene开发手册_第2页
第2页 / 共46页
Lucene开发手册_第3页
第3页 / 共46页
资源描述:

《Lucene开发手册》由会员分享,可在线阅读,更多相关《Lucene开发手册(46页珍藏版)》请在装配图网上搜索。

1、LUCENE开发部署指导手册昆明南天开发中心编者:陈俊昆明南天电脑系统有限公司2010年8月第1章 引言1.1 前言l 编制本手册的目的:1描述Lucene用途,使开发人员依据本手册初步认识Lucene;2描述Lucene的API,使开发人员可以快速认识并利用Lucene开发搜索引擎;3描述Lucene和webdt的融合;4. 重点描述Lucene的应用,使开发人员可按照本手册的描述开发。l 本手册面向的读者:熟悉Java开发,并对WEBDT软件的特点(请参阅技术白皮书)具有初步认识的技术人员。1.2 概述本手册首先介绍了Lucene的概念,详细描述了简单快速地将Lucene融入WEBDT运行

2、平台并进行实际开发的方法,使技术人员对Lucene有一个概要性的框架认识,为下一步开发工作奠定基础。第2章 LUCENE 简介2.1 什么是LUNCENELucene是一套java API,就如同Servlet是一套API一样。Lucene不是一个独立的搜索引擎系统,但是你可以使用Luncene来开发搜索引擎系统。这正如Servlet不是网站系统但是你可以用Servlet开发网站一样。有人已经用Lucene开发出了独立的搜索引擎系统,你可以下载,然后不写一行代码就是用它。Nutch是最出名的了。Lucene是一个全文搜索框架,而不是应用产品。因此它并不像 或者google Desktop那么拿

3、来就能用,它只是提供了一种工具让你能实现这些产品。 2.2 LUNCENE能做什么要回答这个问题,先要了解Lucene的本质。实际上Lucene的功能很单一,说到底,就是你给它若干个字符串,然后它为你提供一个全文搜索服务,告诉你你要搜索的关键词出现在哪里。知道了这个本质,你就可以发挥想象做任何符合这个条件的事情了。你可以把站内新闻都索引了,做个资料库;你可以把一个数据库表的若干个字段索引起来,那就不用再担心因为“%like%”而锁表了;你也可以写个自己的搜索引擎 2.3 你该不该选择Lucene 下面给出一些测试数据,如果你觉得可以接受,那么可以选择。 测试一:250万记录,300M左右文本,

4、生成索引380M左右,800线程下平均处理时间300ms。 测试二:37000记录,索引数据库中的两个Varchar字段,索引文件2.6M,800线程下平均处理时间1.5ms。第3章 LUCENE 的 概述3.1 下载LUCENE进入Lucene的主页:。可以从主页中单击“free download”链接,从而转入http:/www.apache.org/dyn/closer.cgi/lucen/java/页面,这是网站为访问者推荐的最佳镜像地址,从这里往往可以得到最快的下载速度。单击页面中推荐的镜像地址,进入Lucene的下载页面:http:/government-grants.org/mi

5、rrors/apache.org/lucene/java。从页面中选择lucene-。3.2 LUCENE基本概念3.2.1 AnalyzerAnalyzer是分析器,它的作用是把一个字符串按某种规则划分成一个个词语,并去除其中的无效词语,这里说的无效词语是指英文中的“of”、 “the”,中文中的“的”、“地”等词语,这些词语在文章中大量出现,但是本身不包含什么关键信息,去掉有利于缩小索引文件、提高效率、提高命中率。 分词的规则千变万化,但目的只有一个:按语义划分。这点在英文中比较容易实现,因为英文本身就是以单词为单位的,已经用空格分开;而中文则必须以某种方法将连成一片的句子划分成一个个词语

6、。具体划分方法下面再详细介绍,这里只需了解分析器的概念即可。 3.2.2 Document用户提供的源是一条条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。一条记录经过索引之后,就是以一个Document的形式存储在索引文件中的。用户进行搜索,也是以Document列表的形式返回。 3.2.3 Field一个Document可以包含多个信息域,例如一篇文章可以包含“标题”、“正文”、“最后修改时间”等信息域,这些信息域就是通过Field在Document中存储的。 Field有两个属性可选:存储和索引。通过存储属性你可以控制是否对这个Field进行存储;通过索引属性你可以控制是否

7、对该Field进行索引。这看起来似乎有些废话,事实上对这两个属性的正确组合很重要,下面举例说明: 还是以刚才的文章为例子,我们需要对标题和正文进行全文搜索,所以我们要把索引属性设置为真,同时我们希望能直接从搜索结果中提取文章标题,所以我们把标题域的存储属性设置为真,但是由于正文域太大了,我们为了缩小索引文件大小,将正文域的存储属性设置为假,当需要时再直接读取文件;我们只是希望能从搜索解果中提取最后修改时间,不需要对它进行搜索,所以我们把最后修改时间域的存储属性设置为真,索引属性设置为假。上面的三个域涵盖了两个属性的三种组合,还有一种全为假的没有用到,事实上Field不允许你那么设置,因为既不存

8、储又不索引的域是没有意义的。 3.2.4 Termterm是搜索的最小单位,它表示文档的一个词语,term由两部分组成:它表示的词语和这个词语所出现的field。 3.2.5 Tockentocken是term的一次出现,它包含trem文本和相应的起止偏移,以及一个类型字符串。一句话中可以出现多次相同的词语,它们都用同一个term表示,但是用不同的tocken,每个tocken标记该词语出现的地方。 3.2.6 Segment添加索引时并不是每个document都马上添加到同一个索引文件,它们首先被写入到不同的小文件,然后再合并成一个大索引文件,这里每个小文件都是一个segment。 3.3

9、Lucene的结构Lucene包括core和sandbox两部分,其中core是Lucene稳定的核心部分,sandbox包含了一些附加功能,例如highlighter、各种分析器。 Lucene core有七个包:analysis,document,index,queryParser,search,store,util。 3.3.1 analysis Analysis包含一些内建的分析器,例如按空白字符分词的WhitespaceAnalyzer,添加了stopwrod过滤的StopAnalyzer,最常用的StandardAnalyzer。 3.3.2 document Document包含

10、文档的数据结构,例如Document类定义了存储文档的数据结构,Field类定义了Document的一个域。 3.3.3 index Index包含了索引的读写类,例如对索引文件的segment进行写、合并、优化的IndexWriter类和对索引进行读取和删除操作的 IndexReader类,这里要注意的是不要被IndexReader这个名字误导,以为它是索引文件的读取类,实际上删除索引也是由它完成, IndexWriter只关心如何将索引写入一个个segment,并将它们合并优化;IndexReader则关注索引文件中各个文档的组织形式。 3.3.4 queryParser QueryPar

11、ser包含了解析查询语句的类,Lucene的查询语句和sql语句有点类似,有各种保留字,按照一定的语法可以组成各种查询。 Lucene有很多种Query类,它们都继承自Query,执行各种特殊的查询,QueryParser的作用就是解析查询语句,按顺序调用各种 Query类查找出结果。 3.3.5 SearchSearch包含了从索引中搜索结果的各种类,例如刚才说的各种Query类,包括TermQuery、BooleanQuery等就在这个包里。 4.6 store Store包含了索引的存储类,例如Directory定义了索引文件的存储结构,FSDirectory为存储在文件中的索引,RAM

12、Directory为存储在内存中的索引,MmapDirectory为使用内存映射的索引。 3.3.6 UtilUtil包含一些公共工具类,例如时间和字符串之间的转换工具。 3.4 如何建索引3.4.1 创建Field创建File的方法有很多种,下面是最常用的方法。Field field= new Field(Field 名称,Field 内容,存储方式,索引方式);这四个参数的含义如下:(1) Field 名称就是为Field取得名字,类似数据表的字段名称。(2) Field 内容就是该Field 的内容,类似数据表的字段内容。(3) 存储方式包括三种:不存储(Field.Store.NO)、

13、完全存储(Field.Store.YES)和压缩存储()通常,如果不担心索引太大的话,可以可以都使用完全存储的方式。但是,出于对性能的考虑,索引文件的内容是越小越好。因此,如果Field的内容很少就采用完全存储(如标题),如果Field的内容很多就采用不存储或压缩存储的方式(如正文)。(4)索引方式包括四种:不索引(Field.Store.NO)、索引但不分析(Filed.Index.NO_NORMS)、索引但不分词(Field.Index.UN_TOKENIZED)、分次并索引(Field.Index. TOKENIZED)。以新闻稿为例,通常我们会按照标题和全文进行模糊搜索,这类需要进行模

14、糊搜索的字段就用Field.Index. TOKENIZED。通常我们会按照作者名称进行精确搜索,需要精心精确搜索的字段就用Field.Index.UN_TOKENIZED。对于那些只需要跟着搜索结果显示出来却不需要按照其内容进行搜索的字段,使用Field.Index.NO。3.4.2 创建Document创建Document的方法如下:Document doc= new Document();这个方法用来创建一个不含任何Field的空Document。如果想把Field添加到Document里面,只需使用add方法。例如doc.add(field);重复的使用这个方法,就可以将多个Field

15、加入到一个Document里面。3.4.3 创建IndexWriter创建IndexWriter的方法很多,下面是最常用的方法:IndexWriter writer= new IndexWriter(存储索引的路径,分析器的实例);这两个参数的含义如下:(1) 存储索引的路径就是索引被存储在硬盘上的物理路径。如:c:my等。(2) 分析器的实例。分析器是用来做词法分析的,包括英文分析器和中文分析器等。要根据所要建立索引的文件情况选择适当的分析器。常用的有StandardAnalyzer(标准分析器)、CJKAnaLyzer(二分法分析器)、ChineseAnlyzer(中文分析器)和Frenc

16、hAnalyzer(法语分析器)等。可以根据自己的需要去编写分析器,从而处理不同的语言文字。通过建立IndexWriter,就把逻辑索引核物理索引联系起来了,这样就可以很方便的建立索引。例如:IndexWriter wrier=new IndexWriter(“c:/my/index”,new CJKAnalyzer());这是使用二分法分次器来分析字段内容,然后建索引建立在C:/gad/index目录下。使用 new IndexWriter() 方法建立起来的是一个空索引器,要把Document添加到索引中来,需要使用addDocument方法。例如:writer.addDocument()

17、;这类似于我们前面提到过的向Document中添加Field,重复执行这个操作就可以向一个IndexWriter中添加多个Field。最后,在索引创建完成之时,要使用close方法关闭索引器。例如:writer.close(); 最简单的能完成索引的代码片断Java代码 1. IndexWriterwriter=newIndexWriter(“/data/index/”,newStandardAnalyzer(),true); 2. Documentdoc=newDocument(); 3. doc.add(newField(title,Luceneintroduction,Field.Sto

18、re.YES,Field.Index.TOKENIZED); 4. doc.add(newField(content,Luceneworkswell,Field.Store.YES,Field.Index.TOKENIZED); 5. writer.addDocument(doc); 6. writer.optimize(); 7. writer.close();IndexWriter writer = new IndexWriter(“/data/index/”, new StandardAnalyzer(), true);Document doc = new Document();doc.

19、add(new Field(title, lucene introduction, Field.Store.YES, Field.Index.TOKENIZED);doc.add(new Field(content, lucene works well, Field.Store.YES, Field.Index.TOKENIZED);writer.addDocument(doc);writer.optimize();writer.close();下面我们分析一下这段代码。 首先我们创建了一个writer,并指定存放索引的目录为“/data/index”,使用的分析器为StandardAnaly

20、zer,第三个参数说明如果已经有索引文件在索引目录下,我们将覆盖它们。 然后我们新建一个document。 我们向document添加一个field,名字是“title”,内容是“Lucene introduction”,对它进行存储并索引。 再添加一个名字是“content”的field,内容是“Lucene works well”,也是存储并索引。 然后我们将这个文档添加到索引中,如果有多个文档,可以重复上面的操作,创建document并添加。 添加完所有document,我们对索引进行优化,优化主要是将多个segment合并到一个,有利于提高索引速度。 随后将writer关闭,这点很重要

21、。 3.5 执行搜索索引创建好以后,就可以执行搜索了。执行搜索的过程就是:将用户输入的关键字处理,从而得到搜索结果。使用Lucene执行搜索,首先要创建IndexSearcher对象,然后要通过Term和Query对象来封装用户输入的搜索条件,最后将结果封装在Hits对象中,返回给用户。3.5.1 创建搜索器对象:IndexSearcher创建IndexSearcher对象的方法如下:IndexSearcher searcher= new IndexSearcher(索引存放路径);创建IndexSearcher对象很容易,创建完成之后,就可以使用它进行搜索了。它最常用的方法是search()

22、。使用search 方法将返回一个结果集对象,即Hits。例如:Hits h =searcher.search();搜索执行完毕之后,应该使用close()方法关闭IndexSearcher对象。例如:Searcher.close();3.5.2 封装搜索条件:使用Term和Query 对象如果我们要从一个索引中搜索“title”字段包含“中国”的文档,该怎么办?这时,用户的搜索条件是Field为title,关键词为“中国”。创建Trem对象来封装这个搜索条件,可用:Term t= new Term(“title”,“中国”);由此可见Term对象的创建方法,即:Term t=new Term

23、(“字段名称”,“关键字”);然后,我们要创建一个Query对象,从而把Term对象转化成可执行的查询条件。Query对象有很多种,我们暂时只介绍最简单的TermQuery对象。用法如下:Query q =new TermQuery(t);至此,用户的搜索请求就被封装好了,封装在Query对象中。3.5.2.1 各种各样的Query下面我们看看Lucene到底允许我们进行哪些查询操作: TermQuery 首先介绍最基本的查询,如果你想执行一个这样的查询:“在content域中包含Lucene的document”,那么你可以用TermQuery: Term t = new Term(conte

24、nt, Lucene; Query query = new TermQuery(t); BooleanQuery 如果你想这么查询:“在content域中包含java或perl的document”,那么你可以建立两个TermQuery并把它们用BooleanQuery连接起来:Java代码 1. TermQuerytermQuery1=newTermQuery(newTerm(content,java); 2. TermQuerytermQuery2=newTermQuery(newTerm(content,perl); 3. BooleanQuerybooleanQuery=newBoole

25、anQuery(); 4. booleanQuery.add(termQuery1,BooleanClause.Occur.SHOULD); 5. booleanQuery.add(termQuery2,BooleanClause.Occur.SHOULD);TermQuery termQuery1 = new TermQuery(new Term(content, java);TermQuery termQuery 2 = new TermQuery(new Term(content, perl);BooleanQuery booleanQuery = new BooleanQuery();

26、booleanQuery.add(termQuery 1, BooleanClause.Occur.SHOULD);booleanQuery.add(termQuery 2, BooleanClause.Occur.SHOULD);WildcardQuery 如果你想对某单词进行通配符查询,你可以用WildcardQuery,通配符包括?匹配一个任意字符和*匹配零个或多个任意字符,例如你搜索use*,你可能找到useful或者useless:Java代码 1. Queryquery=newWildcardQuery(newTerm(content,use*);Query query = new

27、 WildcardQuery(new Term(content, use*);PhraseQuery 你可能对中日关系比较感兴趣,想查找中和日挨得比较近(5个字的距离内)的文章,超过这个距离的不予考虑,你可以:Java代码 1. PhraseQueryquery=newPhraseQuery(); 2. query.setSlop(5); 3. query.add(newTerm(content,“中”); 4. query.add(newTerm(“content”,“日”);PhraseQuery query = new PhraseQuery();query.setSlop(5);que

28、ry.add(new Term(content , “中”);query.add(new Term(“content”, “日”);那么它可能搜到“中日合作”、“中方和日方”,但是搜不到“中国某高层领导说日本欠扁”。 PrefixQuery 如果你想搜以中开头的词语,你可以用PrefixQuery:Java代码 1. PrefixQueryquery=newPrefixQuery(newTerm(content,中);PrefixQuery query = new PrefixQuery(new Term(content , 中);FuzzyQuery FuzzyQuery用来搜索相似的ter

29、m,使用Levenshtein算法。假设你想搜索跟wuzza相似的词语,你可以:Java代码 1. Queryquery=newFuzzyQuery(newTerm(content,wuzza);Query query = new FuzzyQuery(new Term(content, wuzza);你可能得到fuzzy和wuzzy。 RangeQuery 另一个常用的Query是RangeQuery,你也许想搜索时间域从20060101到20060130之间的document,你可以用RangeQuery:Java代码 1. RangeQueryquery=newRangeQuery(ne

30、wTerm(“time”,“20060101”),newTerm(“time”,“20060130”),true);RangeQuery query = new RangeQuery(new Term(“time”, “20060101”), new Term(“time”, “20060130”), true);最后的true表示用闭合区间。3.5.2.2 QueryParser看了这么多Query,你可能会问:“不会让我自己组合各种Query吧,太麻烦了!”当然不会,Lucene提供了一种类似于SQL语句的查询语句,我们姑且叫它Lucene语句,通过它,你可以把各种查询一句话搞定,Luce

31、ne会自动把它们查分成小块交给相应Query执行。下面我们对应每种Query演示一下: TermQuery可以用“field:key”方式,例如“content:Lucene”。 BooleanQuery中与用+,或用 ,例如“content:java contenterl”。 WildcardQuery仍然用?和*,例如“content:use*”。 PhraseQuery用,例如“content:中日5”。 PrefixQuery用*,例如“中*”。 FuzzyQuery用,例如“content: wuzza ”。 RangeQuery用或,前者表示闭区间,后者表示开区间,例如“time:

32、20060101 TO 20060130”,注意TO区分大小写。 你可以任意组合query string,完成复杂操作,例如“标题或正文包括Lucene,并且时间在20060101到20060130之间的文章”可以表示为:“+ (title:Lucene content:Lucene) +time:20060101 TO 20060130”。代码如下:Java代码 1. Directorydir=FSDirectory.getDirectory(PATH,false); 2. IndexSearcheris=newIndexSearcher(dir); 3. QueryParserparser

33、=newQueryParser(content,newStandardAnalyzer(); 4. Queryquery=parser.parse(+(title:Lucenecontent:Lucene)+time:20060101TO20060130; 5. Hitshits=is.search(query); 6. for(inti=0;ihits.length();i+) 7. 8. Documentdoc=hits.doc(i); 9. System.out.println(doc.get(title); 10. 11. is.close();Directory dir = FSDi

34、rectory.getDirectory(PATH, false);IndexSearcher is = new IndexSearcher(dir);QueryParser parser = new QueryParser(content, new StandardAnalyzer();Query query = parser.parse(+(title:lucene content:lucene) +time:20060101 TO 20060130;Hits hits = is.search(query);for (int i = 0; i hits.length(); i+)Docum

35、ent doc = hits.doc(i);System.out.println(doc.get(title);is.close();首先我们创建一个在指定文件目录上的IndexSearcher。 然后创建一个使用StandardAnalyzer作为分析器的QueryParser,它默认搜索的域是content。 接着我们用QueryParser来parse查询字串,生成一个Query。 然后利用这个Query去查找结果,结果以Hits的形式返回。 这个Hits对象包含一个列表,我们挨个把它的内容显示出来。 3.5.2.3 Filterfilter的作用就是限制只查询索引的某个子集,它的作用有

36、点像SQL语句里的where,但又有区别,它不是正规查询的一部分,只是对数据源进行预处理,然后交给查询语句。注意它执行的是预处理,而不是对查询结果进行过滤,所以使用filter的代价是很大的,它可能会使一次查询耗时提高一百倍。 最常用的filter是RangeFilter和QueryFilter。RangeFilter是设定只搜索指定范围内的索引;QueryFilter是在上次查询的结果中搜索。 Filter的使用非常简单,你只需创建一个filter实例,然后把它传给searcher。继续上面的例子,查询“时间在20060101到20060130之间的文章”除了将限制写在query strin

37、g中,你还可以写在RangeFilter中:Java代码 1. Directorydir=FSDirectory.getDirectory(PATH,false); 2. IndexSearcheris=newIndexSearcher(dir); 3. QueryParserparser=newQueryParser(content,newStandardAnalyzer(); 4. Queryquery=parser.parse(title:Lucenecontent:Lucene; 5. RangeFilterfilter=newRangeFilter(time,20060101,200

38、60230,true,true); 6. Hitshits=is.search(query,filter); 7. for(inti=0;ihits.length();i+) 8. 9. Documentdoc=hits.doc(i); 10. System.out.println(doc.get(title); 11. 12. is.close();Directory dir = FSDirectory.getDirectory(PATH, false);IndexSearcher is = new IndexSearcher(dir);QueryParser parser = new Qu

39、eryParser(content, new StandardAnalyzer();Query query = parser.parse(title:lucene content:lucene;RangeFilter filter = new RangeFilter(time, 20060101, 20060230, true, true);Hits hits = is.search(query, filter);for (int i = 0; i hits.length(); i+)Document doc = hits.doc(i);System.out.println(doc.get(t

40、itle);is.close();3.5.2.4 Sort有时你想要一个排好序的结果集,就像SQL语句的“order by”,Lucene能做到:通过Sort。 Sort sort = new Sort(“time”); /相当于SQL的“order by time” Sort sort = new Sort(“time”, true); / 相当于SQL的“order by time desc” 下面是一个完整的例子:Java代码 1. Directorydir=FSDirectory.getDirectory(PATH,false); 2. IndexSearcheris=newIndex

41、Searcher(dir); 3. QueryParserparser=newQueryParser(content,newStandardAnalyzer(); 4. Queryquery=parser.parse(title:Lucenecontent:Lucene; 5. RangeFilterfilter=newRangeFilter(time,20060101,20060230,true,true); 6. Sortsort=newSort(“time”); 7. Hitshits=is.search(query,filter,sort); 8. for(inti=0;ihits.l

42、ength();i+) 9. 10. Documentdoc=hits.doc(i); 11. System.out.println(doc.get(title); 12. is.close();3.5.3 执行搜索用户的搜索请求被封装好了之后,就该把请求传递给IndexSearcher对象,使其执行搜索。IndexSearcher对象调用search方法,以Query对象为参数,返回搜索结果,封装在Hits对象中。如下所示:Hits hs=searcher.search(q);3.5.4 提取搜索结果:了解Hits对象搜索结果被封装在Hits对象中,要想从中得到结果的具体内容,就需要了解Hi

43、ts对象的相关方法和属性。我们知道,搜索结果是由一组Document构成的,所以,只要从Hits对象中获得这些Document,之后就可以从Document中取得Field,进而得到原文档的一切内容。Hits对象有如下常用方法:(1) Document doc(int n) 返回指定序号的Document。(2) int id(int n) 返回指定序号的Document的id属性。(3) int length() 返回Hits对象的长度,也就是Hits对象中包含的Document的数量。(4) float score(int n) 返回指定序号的Document的score属性(即文档得分)

44、。有了这些方法,我们就可以灵活地操作搜索结果。3.5.5 提取搜索结果:了解Document对象在从Hits对象中提取出Document之后,想要获取这个Document中含有的具体内容时,就要了解他的一些常用方法。(1) Field getField(String name)参数是Field名称,返回值是该Field对象。(2) List getFields()无参数,返回值是List类型,包含该Document的所有Field。(3) Enumeration fields()无参数,返回值是Enumeration类型,包含该Document的所有Field。(4) String get(S

45、tring name)参数是Field名称,返回值是该Field对象的字符串值。3.5.6 提取搜索结果:了解Field对象使用Document对象的相关方法获得Field对象之后,就可以跳用Field对象的方法来获得详细信息。Field对象的常用方法如下:(1)byte binary Vakue()获得指定Field对象的二进制值。(2)Reader readerValue()获得指定Field对象的内容,以Reader形式返回。(3)String stringValue()获得指定Field对象的字符串值,这个方法是最常用的。3.6 中文分词3.6.1 分词的方法 分词的方法主要有以下几种

46、:(1) 单字切分 单字切分就是把一段文字按照每个字去建立索引。如果用来切分“我爱你”,就会切成“我”,“爱”,“你”3个词。这种分此法效率低,但也能解决一些问题。(2) 二分法二分法就是把一段文字的每两个相邻的字算做一个词。如果用来切分“我爱你”,就切成“我爱”,“爱你”。这种分词法效率也低,但比单字切分好得多。(3) 词典法词典法就是建立一个词典文件,然后使用词典和文字段落进行匹配,从而得出分此结果。在这种分此方法中,词典和匹配算法是关键。(5) 语义法3.6.2 LUCENE的分词器3.6.2.1 二分法分词器 在Lucene软件包的contrib/analyzers目录下有一个luce

47、ne-analyzers-.jar文件,其中含有二分法分词器CJKAnalyzer。只需将此jar放入编译路径即可使用CJKAnalyzer。 分词效果:“我爱你”,切成“我爱”,“爱你”。3.6.2.2 Lucene自带的中文分词器 在Lucene软件包的contrib/analyzers目录下有一个lucene-analyzers-.jar文件,其中含有二分法分词器ChineseAnalyzer。只需将此jar放入编译路径即可使用ChineseAnalyzer,这个分词器目前使用的是单字切分。 分词效果:“我爱你”,切成“我”,“爱”,“你”。3.6.2.3 NGram分词器的原理和用法在

48、Lucene软件包的contrib/analyzers目录下有一个lucene-analyzers-.jar文件,其中含有二分法分词器NGramTokenizer。只需将此jar放入编译路径即可使用NGramTokenizer,这个分词器目前使用的是单字切分。 分词效果:“我爱你”,切成“我|爱|你”,“我爱|爱你”,“我|我爱|爱你|你”。3.6.2.4 JE分词器的原理和用法 JE分词器是一个不错的分词器,许多人都在使用。可以从上面下载。最新版(2007-5-31)的JE分词器是,基于词库,可以向词库中增加新词。 将je-analysis-.jar放到编译路径中即可使用。 分词效果:“我爱

49、你”,切成“我|爱你”。除了以上列举的分词器之外,网上还有其他一些免费的分词器,大家可以更多的了解。3.7 数据解析数据解析的方法有很多种,这里重点介绍Lius类库。3.7.1 初识Lius3.7.1.1 Lius 简介Lius是一套用于建立索引的java框架,它基于Lucene项目而建。使用Lius框架可以索引Microsoft Word、Microsoft Excel、Microsoft Powerpoint、RTF、PDF、XML、HTML、TXT、OpenOffice套件、Zip文档、MP3、Vcard、Latex和JavaBean文件。3.7.1.2 下载Lius Lius的项目主页

50、是页面上有一个绿色的下载链接,单击它,可以进入Lius的下载列表页面,我们选择最新的版本Lius-1.0。使用Lius1.0,需要Java5环境支持。同时,需要把Lius根目录下的Lius-1.0.jar和lib目录下的外部类库加入到编译路径。3.7.2 借助Lius解析普通数据3.7.2.1 解析Word使用Lius解析Word的方法如下面案例所示。程序名称:LiusWord.java,/ 解析Word文档public String LiusWord(String filepath) WordIndexer wi = new WordIndexer();File f = new File(f

51、ilepath);String content = ;try wi.setStreamToIndex(new FileInputStream(f);content = wi.getContent(); catch (Exception e) e.printStackTrace();return content;3.7.2.2 解析Excel使用Lius解析Excel的方法如下面案例所示。程序名称:LiusExcel.java/ 解析Excel文档public String LiusExcel(String filepath) ExcelIndexer ei = new ExcelIndexer

52、();File f = new File(filepath);String content = ;try ei.setStreamToIndex(new FileInputStream(f);content = ei.getContent(); catch (Exception e) e.printStackTrace();return content;3.7.2.3 解析PDF使用Lius解析PDF的方法如下面案例所示。程序名称:LiusPDF.java/ 解析PDF文档public String LiusPDF(String filepath) PdfIndexer pi = new Pd

53、fIndexer();File f = new File(filepath);String content = ;try pi.setStreamToIndex(new FileInputStream(f);content = pi.getContent(); catch (Exception e) e.printStackTrace();return content;3.7.2.4 解析PowerPoint使用Lius解析PPT的方法如下面案例所示。程序名称:LiusPPT.java/ 解析PPT文档public String LiusPPT(String filepath) PPTInde

54、xer pi = new PPTIndexer();File f = new File(filepath);String content = ;try pi.setStreamToIndex(new FileInputStream(f);content = pi.getContent(); catch (Exception e) e.printStackTrace();return content;Lius解析PowerPoint文件时借助POI组件。POI组件不仅支持Excel解析,而且支持Word、PowerPoint等多种文件格式的解析,只是目前解析质量差,解析方法复杂。目前Lius对P

55、owerPoint文件的解析还不支持中文。如果Lius使用了Jacob组件,然后通过PowerPoint的COM组件操作,就可以获得完好的解析结果。因为目前Lius对PowerPoint文件的解析还不支持中文在这里我使用的是POI组件,先下载 、将它们加入到工程的编译路径。不过这两个包的加入可能会与Lius中的poi-final-20040804冲突,冲突见导致java.lang.NoSuchMethodError: org.apache.poi.poifs.filesystem.POIFSFileSystem.getRoot()Lorg/apache/poi/poifs/filesystem

56、/DirectoryEntry;错误。解析PPT的方法如下:/解析PPT文档 public static String handlePPT(String filename) StringBuffer content = new StringBuffer(); try File file=new File(filename); if(!file.exists() return content.toString(); FileInputStream instream=new FileInputStream(file); SlideShow ppt = new SlideShow(instream)

57、; Slide slides = ppt.getSlides(); for(int i=0;islides.length;i+) TextRun t = slidesi.getTextRuns();/为了取得幻灯片的文字内容,建立TextRun for(int j=0;jt.length;j+) content.append(tj.getText();/这里会将文字内容加到content中去 content.append(slidesi.getTitle(); catch(Exception e) e.printStackTrace(); return content.toString();

58、3.7.2.5 解析TXT使用Lius解析TXT的方法如下面案例所示。程序名称:LiusTXT.java/ 解析TXT文档public static String LiusTXT(String filepath) TXTIndexer ti = new TXTIndexer();File f = new File(filepath);String content = ;try ti.setStreamToIndex(new FileInputStream(f);content = ti.getContent(); catch (Exception e) e.printStackTrace();

59、return content;3.7.2.6 解析HTML使用Lius解析HTML的方法有两个类:JTidyHtmlIndexer和NekoHtmlIndexer。这两个类分别利用了JTidy类库和Neko类库。/ 解析HTML文档1public String LiusJTidy (String filepath) JTidyHtmlIndexer ji = new JTidyHtmlIndexer ();File f = new File(filepath);String content = ;try ji.setStreamToIndex(new FileInputStream(f);content = ji.getContent(); catch (Exceptio

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!