




免费预览已结束,剩余62页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Lucene.Net 2.3.1开发介绍 简介 Lucene.Net是Lucene在dot net平台上的移植版本。它的功能与Lucene一样,都是用来提供一组API,让我们能快速开发自己的搜索引擎,当然,是全文搜索。它不是一个程序,拿 到它并不能立刻运行,你必须自己实现逻辑过程。这是一个和.Net Framework一样的框架。Lucene是用Java写的,尔后衍生出Nutch,接着又衍生出Hadoop。这些可以说和Lucene没有内在联 系,但是它们可以扩充Lucene的应用规模。目前,在dot net平台,还没发现有Nutch和Hadoop的移植程序。不过有了Lucene.Net就该庆幸了,已经能够做很多事情。Lucene和Lucene.Net目前都是Apache基金会的开源项目。Java版的可以在这里找到:/; dotNet版的可以在这里找到:// 目前,Java版的最新版本是2.3.2,而Lucene.Net则是2.3.1。最新的源码可以从这里下载/repos/asf/incubator//trunk/,当然,必须用svn下载。详细请看Lucene.Net 2.3.1开发介绍附录一、如何下载Lucene.Net的各种版本 。 Lucene.Net 2.3.1开发介绍附录一、如何下载Lucene.Net的各种版本 首先,你需要一个svn客户端。TortoiseSVN非常好用,可以从官方网站下载。下载地址:/downloads。下载完成,就安装,需要重启电脑。然后在d盘下建立一个空文件夹,命名为Lucene.Net。打开文件夹,右键,则出现菜单。如图附录一 1。附录一 1发现多了两项,分别是SVN Checkout和TortoiseSVN。点“SVN Checkout”,出现“附录一 2”界面。附录一 2在URL of repository框输入/repos/asf/incubator//trunk/,然后点OK,就可以下载到最新版本。历史版本在/repos/asf/incubator//tags/目录,可以用浏览器打开查看。然后按上述步骤就可以下载。Lucene.Net 2.3.1开发介绍 一、接触Lucene.Net 1、引用Lucene.Net类库找到Lucene.Net的源代码,在“C#srcLucene.Net”目录。打开Visual Studio,我的版本是2008,而Lucene.Net默认的是2005。先创建一个项目,简单起见,创建一个C#控制台程序。图 1.1然后添加Lucene.Net进项目,如图 1.2 - 1.3。图 1.2图 1.3这个过程要进行一个VS2005到2008的转换。添加后,解决方案就有Lucene.Net项目了,如图1.4。图 1.4然后把Lucene.Net引入TestLucene项目。如图1.5 -1.6:图1.5图1.6点确定后就可以了。这时候,就可以在TestLucene项目中使用Lucene.Net的API了。2、简单示例对Lucene.Net的操作分为建立索引,和搜索两部分。2.1 建立索引通过代码 2.1.1,就可以简单地建立一个索引了。代码 2.1.1将在应用程序目录下建立一个IndexDirectory目录,并在目录下创建索引文件。代码 2.1.1Code1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;456namespaceTestLucene78usingLucene.Net.Index;9usingLucene.Net.Store;10usingLucene.Net.Analysis;11usingLucene.Net.Analysis.Standard;12usingLucene.Net.Documents;1314classProgram1516staticvoidMain(stringargs)1718Analyzeranalyzer=newStandardAnalyzer();19IndexWriterwriter=newIndexWriter(IndexDirectory,analyzer,true);20AddDocument(writer,SQLServer2008的发布,SQLServer2008的新特性);21AddDocument(writer,ASP.NetMVC框架配置与分析,而今,微软推出了新的MVC开发框架,也就是MicrosoftASP.NET3.5Extensions);22writer.Optimize();23writer.Close();242526staticvoidAddDocument(IndexWriterwriter,stringtitle,stringcontent)2728Documentdocument=newDocument();29document.Add(newField(title,title,Field.Store.YES,Field.Index.TOKENIZED);30document.Add(newField(content,content,Field.Store.YES,Field.Index.TOKENIZED);31writer.AddDocument(document);323334352.2 搜索索引代码2.2.1就可以搜索刚才建立的索引。代码 2.2.1Code1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;456namespaceTestLucene78usingLucene.Net.Index;9usingLucene.Net.Store;10usingLucene.Net.Analysis;11usingLucene.Net.Analysis.Standard;12usingLucene.Net.Documents;13usingLucene.Net.Search;14usingLucene.Net.QueryParsers;1516classProgram1718staticvoidMain(stringargs)1920Analyzeranalyzer=newStandardAnalyzer();21/IndexWriterwriter=newIndexWriter(IndexDirectory,analyzer,true);22/AddDocument(writer,SQLServer2008的发布,SQLServer2008的新特性);23/AddDocument(writer,ASP.NetMVC框架配置与分析,而今,微软推出了新的MVC开发框架,也就是MicrosoftASP.NET3.5Extensions);24/writer.Optimize();25/writer.Close();2627IndexSearchersearcher=newIndexSearcher(IndexDirectory);28MultiFieldQueryParserparser=newMultiFieldQueryParser(newstringtitle,content,analyzer);29Queryquery=parser.Parse(sql);30Hitshits=searcher.Search(query);3132for(inti=0;ihits.Length();i+)3334Documentdoc=hits.Doc(i);35Console.WriteLine(string.Format(title:0content:1,doc.Get(title),doc.Get(content);3637searcher.Close();3839Console.ReadKey();404142/staticvoidAddDocument(IndexWriterwriter,stringtitle,stringcontent)43/44/Documentdocument=newDocument();45/document.Add(newField(title,title,Field.Store.YES,Field.Index.TOKENIZED);46/document.Add(newField(content,content,Field.Store.YES,Field.Index.TOKENIZED);47/writer.AddDocument(document);48/495051运行后输出:title:SQL Server 2008 的发布 content:SQL Server 2008 的新特性2.3 疑问2.1,2.2小节介绍了最简单的建立和搜索索引的方式。虽然代码很短,使用也很简单,但是理解起来却不是太容易。代码 2.1.1中,先是建立了一个分词器。什么是分词器?为什么要有分词器?分词器是怎么工作的?这些问题真让人头疼。接着建立一个IndexWriter的 实例,这个类是负责创建索引的,有很多构造函数,这里使用的是其中的一个。三个参数分别是:索引建立到哪个目录,用什么分词器,还有就是是否创建。如果是 否创建为false,那么就是以增量的方式来创建。再下来调用了AddDocument方法,在AddDocument方法中,先组织一个 Docuement对象,然后把这个对象交给IndexWriter。然后再调用Optimize优化索引,最后关闭创建过程。这里面又有什么是Document,Document是怎么往存储器里写入的?Optimize方法能干什么?问题真多。代码2.2.1则相对简单,先是创建IndexSearcher对象实例,并指定其搜索的目录,然后构造了一个查询Query,然后查出Hits,这样就得到想要的结果了。但是这个查询的过程是什么样的呢?这个Query代表什么?Hits是怎么得出来的?结果的顺序是怎么决定的?这些又是留下来的问题。这么多问题,不能一次说完,欲知后事如何,下面一一道来。Lucene.Net 2.3.1开发介绍 二、分词(一) Lucene.Net中,分词是核心库之一,当然,也可以将它独立出来。目前Lucene.Net的分词库很不完善,实际应用价值不高。唯一能用在实际场合的StandardAnalyzer类,效果也不是很好。内置在Lucene.Net里的分词都被放在项目的Analysis目录下,也就是Lucene.Net.Analysis命名空间下。分词类的命名一般都是以“Analyzer”结束,比如StandardAnalyzer,StopAnalyzer,SimpleAnalyzer等。全部继承自Analyzer类。而它们一般各有一个辅助类,一般以”“Tokenizer”结尾,分词的逻辑大都在辅助类完成。使用Lucene.Net,要很好地使用Lucene.Net,必须理解分词,甚至能自己扩展分词。如果只使用拉丁语系,那么使用内置的分词可能足够了,但是对于中文肯定是不行的。目前中文方面的分词分为单字分词,二元分词,词库匹配,语义理解这几种。StandardAnalyzer类就是按单字分,二元分就是把两个字作为一组拆分,而词库的话肯定是有一个复杂的对比过程,语义理解的就更加复杂了。这是分词的方式,而匹配的方式也分为正向和逆向两种,一般逆向要优于正向,但是写起来也要复杂一些。1、内置分词器本节将详细介绍Lucene.Net内置分词的效果,工作过程,及整体结构。1.1、分词效果1.1.1 如果得到分词效果如果得到分词效果?有效的方式就是进行测试。这里将引入自动测试的方法,这样更加便于测试,将使用NUnit来完成。Nunit的简单实用方法见附录二。创建一个新的项目,命名为Test。步骤如图 - 图图 点确定,就加入了新项目Test,选择类库模板。再引用Nunit.framework类库。如图 。图 再按第一章节的步骤引入Lucene.Net类库。先来试试SimpleAnalyzer类的效果。在Test项目中添加SimpleAnalyzerTest,代码 。代码 Code1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;4usingNUnit.Framework;5usingLucene.Net.Analysis;6usingSystem.IO;7namespaceTest89TestFixture10publicclassSimpleAnalyzerTest1112Test13publicvoidReusableTokenStreamTest()1415stringtestwords=我是中国人,Icanspeakchinese!;1617SimpleAnalyzersimple=newSimpleAnalyzer();18TokenStreamts=simple.ReusableTokenStream(,newStringReader(testwords);19Tokentoken;20while(token=ts.Next()!=null)2122Console.WriteLine(token.TermText();2324ts.Close();25262728运行结果:我是中国人icanspeakchinese查看这个结果,基本可以确定,SimpleAnalyzer分词就是以空格或符号为断点,把句子分析出来。对于英文大写还会执行一个转换到小写的操作。1.1.2 内置分词的分词效果按照1.1.1节介绍的方式,就可以分析分析效果了。不过这样写出来的测试代码过于麻烦,改造一下。(1)、在Test项目中新建Analysis目录;(2)、在Analysis下建立TestData类,代码;代码Code1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;45namespaceTest.Analysis67publicclassTestData89publicstaticstringTestWords=我是中国人,Icanspeakchinese!;101112(3)、建立TestFactory类,代码代码Code1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;4usingLucene.Net.Analysis;5usingSystem.IO;67namespaceTest.Analysis89publicclassTestFactory1011publicstaticvoidTestFunc(Analyzeranalyzer)1213TokenStreamts=analyzer.ReusableTokenStream(,newStringReader(TestData.TestWords);14Tokentoken;15while(token=ts.Next()!=null)1617Console.WriteLine(token.TermText();1819ts.Close();202122(4)、建立AllAnalysisTest类,代码代码Code1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;4usingNUnit.Framework;5usingLucene.Net.Analysis;6usingLucene.Net.Analysis.Standard;7namespaceTest.Analysis89TestFixture10publicclassAllAnalysisTest1112Test13publicvoidTestMethod()1415Listanalysis=newList()16newKeywordAnalyzer(),17newSimpleAnalyzer(),18newStandardAnalyzer(),19newStopAnalyzer(),20newWhitespaceAnalyzer();2122for(inti=0;ianalysis.Count;i+)2324Console.WriteLine(analysisi.ToString()+结果:);25Console.WriteLine(-);26TestFactory.TestFunc(analysisi);27Console.WriteLine(-);2829303132(5)、运行。对于TestWords = 我是中国人,I can speak chinese!;测试结果:Lucene.Net.Analysis.KeywordAnalyzer结果:-我是中国人,I can speak chinese!-Lucene.Net.Analysis.SimpleAnalyzer结果:-我是中国人icanspeakchinese-Lucene.Net.Analysis.Standard.StandardAnalyzer结果:-我是中国人icanspeakchinese-Lucene.Net.Analysis.StopAnalyzer结果:-我是中国人icanspeakchinese-Lucene.Net.Analysis.WhitespaceAnalyzer结果:-我是中国人,Icanspeakchinese!-换一句话试试:更改TestData类TestWords字段值为“我是中国人,Ican speak chinese,,沪江小Q!”。测试结果:Lucene.Net.Analysis.KeywordAnalyzer结果:-我是中国人,Ican speak chinese,,沪江小Q!-Lucene.Net.Analysis.SimpleAnalyzer结果:-我是中国人icanspeakchinese沪江小q-Lucene.Net.Analysis.Standard.StandardAnalyzer结果:-我是中国人icanspeakchinese沪江小q-Lucene.Net.Analysis.StopAnalyzer结果:-我是中国人icanspeakchinese沪江小q-Lucene.Net.Analysis.WhitespaceAnalyzer结果:-我是中国人,Icanspeakchinese,,沪江小Q!-对于这几种分词效果基本可以看出来了。KeywordAnalyzer分词,没有任何变化;SimpleAnalyzer对中文效果太差;StandardAnalyzer对中文单字拆分;StopAnalyzer和SimpleAnalyzer差不多;WhitespaceAnalyzer只按空格划分。当然,这只是个粗略的结果。Lucene.Net 2.3.1开发介绍 二、分词(二) 1.2、分词的过程1.2.1、分词器工作的过程内置的分词器效果都不好,那怎么办?只能自己写了!在写之前当然是要先看看内置的分词器是怎么实现的了。从1.1分析分词效果,可以看出 KeywordAnalyzer这个分词器最懒惰,基本什么事情也没做。并不是它不会做,而是我们没找到使用它的方法,就像手上拿着个盒子,不知道里面是 什么,就不知道这个是干嘛的,有什么用。打开盒子,那就是要查看源代码了!代码 Code1usingSystem;23namespaceLucene.Net.Analysis456/*/Tokenizestheentirestreamasasingletoken.Thisisuseful7/fordatalikezipcodes,ids,andsomeproductnames.8/9publicclassKeywordAnalyzer:Analyzer1011publicoverrideTokenStreamTokenStream(System.StringfieldName,System.IO.TextReaderreader)1213returnnewKeywordTokenizer(reader);141516publicoverrideTokenStreamReusableTokenStream(System.StringfieldName,System.IO.TextReaderreader)1718Tokenizertokenizer=(Tokenizer)GetPreviousTokenStream();19if(tokenizer=null)2021tokenizer=newKeywordTokenizer(reader);22SetPreviousTokenStream(tokenizer);2324else25tokenizer.Reset(reader);26returntokenizer;272829代码 就是传说中的源码了。先看看注释,意思大体是“Tokenizes整体的流变成一个个词。这个特别适用于邮编,ID,和商品名称。”Tokenizes应该是拆分的意思,字典上查不到这个词。这段代码比较简单,只有两个方法,而第二个方法就是我们先前分析结果的时候用的(见段落1.1)。关键点就在于调用了KeywordTokenizer类。切到KeywordTokenizer类查看一下。代码Code1usingSystem;23namespaceLucene.Net.Analysis456/*/Emitstheentireinputasasingletoken.7publicclassKeywordTokenizer:Tokenizer8910privateconstintDEFAULT_BUFFER_SIZE=256;1112privatebooldone;1314publicKeywordTokenizer(System.IO.TextReaderinput):this(input,DEFAULT_BUFFER_SIZE)15161718publicKeywordTokenizer(System.IO.TextReaderinput,intbufferSize):base(input)1920this.done=false;212223publicoverrideTokenNext(Tokenresult)2425if(!done)2627done=true;28intupto=0;29result.Clear();30charbuffer=result.TermBuffer();31while(true)3233intlength=input.Read(buffer,upto,buffer.Length-upto);34if(length=0)35break;36upto+=length;37if(upto=buffer.Length)38buffer=result.ResizeTermBuffer(1+buffer.Length);3940result.termLength=upto;41returnresult;4243returnnull;444546publicoverridevoidReset(System.IO.TextReaderinput)4748base.Reset(input);49this.done=false;505152代码 就是KeywordTokenizer的源码。代码量很小,却没有完成全部工作,而是将部分工作交给了父类。关注Lucene的人都可以知道,新版本中, 分词这里换掉了,现在多了一个重载的Next方法。这里不讨论为什么要加这个重载,这篇文章主要是讲应用的。因为取词是用Next方法走的,那么只需要关 注Next方法就可以了。KeywordTokenizer的父类是Tokenizer,但是在Tokenizer里找不到我们想要的关系,但是 Tokenizer又继承自TokenStream。查看TokenStream类。代码 Code12usingSystem;34usingPayload=Lucene.Net.Index.Payload;56namespaceLucene.Net.Analysis789/*/ATokenStreamenumeratesthesequenceoftokens,eitherfrom10/fieldsofadocumentorfromquerytext.11/12/Thisisanabstractclass.Concretesubclassesare:13/14/linkTokenizer,aTokenStream15/whoseinputisaReader;and16/linkTokenFilter,aTokenStream17/whoseinputisanotherTokenStream.18/19/NOTE:subclassesmustoverrideatleastoneoflink20/#Next()orlink#Next(Token).21/2223publicabstractclassTokenStream242526/*/Returnsthenexttokeninthestream,ornullatEOS.27/ThereturnedTokenisafullprivatecopy(not28/re-usedacrosscallstonext()butwillbeslower29/thancallinglink#Next(Token)instead.30/31publicvirtualTokenNext()3233Tokenresult=Next(newToken();3435if(result!=null)3637Payloadp=result.GetPayload();38if(p!=null)3940result.SetPayload(Payload)p.Clone();41424344returnresult;454647/*/Returnsthenexttokeninthestream,ornullatEOS.48/Whenpossible,theinputTokenshouldbeusedasthe49/returnedToken(thisgivesfastesttokenization50/performance),butthisisnotrequiredandanewToken51/maybereturned.Callersmayre-useasingleToken52/instanceforsuccessivecallstothismethod.53/54/Thisimplicitlydefinesacontractbetween55/consumers(callersofthismethod)and56/producers(implementationsofthismethod57/thatarethesourcefortokens):58/59/Aconsumermustfullyconsumethepreviously60/returnedTokenbeforecallingthismethodagain.61/AproducermustcalllinkToken#Clear()62/beforesettingthefieldsinit&returningit63/64/NotethatalinkTokenFilterisconsideredaconsumer.65/66/aTokenthatmayormaynotbeusedtoreturn67/68/nexttokeninthestreamornullifend-of-streamwashit69/70publicvirtualTokenNext(Tokenresult)7172returnNext();737475/*/Resetsthisstreamtothebeginning.Thisisan76/optionaloperation,sosubclassesmayormaynot77/implementthismethod.Reset()isnotneededfor78/thestandardindexingprocess.However,iftheTokens79/ofaTokenStreamareintendedtobeconsu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中级会计考试应对方案试题及答案
- 无人机执照考试中的判断试题及答案
- 持续更新的2024年无人机考试试题及答案
- 消防资源配置管理试题及答案
- 施工技术及流程优化试题及答案
- 分享成功无人机考生的经验与备考专题试题及答案
- 2025年中级会计考试学习资源与试题及答案
- 构建以患者为中心的护理服务创新思路试题及答案
- 收入确认的审计方法试题及答案
- 河南省焦作市普通高中2024-2025学年高三下学期第三次模拟考试数学试题(解析)
- 第18课《井冈翠竹》课件-2024-2025学年统编版语文七年级下册
- 【MOOC】《思想道德与法治》(东南大学)章节中国大学慕课答案
- 卜算子-送鲍浩然之浙东课件
- MOOC 中医与辨证-暨南大学 中国大学慕课答案
- 国家开放大学《高等数学基础》形考任务1-4参考答案
- 脑血管意外的急救课件
- 利浦仓施工方案
- 三调土地利用现状分类和三大地类对应甄选
- 消防工程施工进度计划横道图+进度网络图【建筑施工资料】
- 民族教育发展调研报告3篇
- 金属屋面钢结构工程专项施工方案(51页)
评论
0/150
提交评论