昆明理工大学WEB服务与分布式计算期末报告记录2.docx

上传人:b****7 文档编号:9830722 上传时间:2023-02-06 格式:DOCX 页数:24 大小:619.93KB
下载 相关 举报
昆明理工大学WEB服务与分布式计算期末报告记录2.docx_第1页
第1页 / 共24页
昆明理工大学WEB服务与分布式计算期末报告记录2.docx_第2页
第2页 / 共24页
昆明理工大学WEB服务与分布式计算期末报告记录2.docx_第3页
第3页 / 共24页
昆明理工大学WEB服务与分布式计算期末报告记录2.docx_第4页
第4页 / 共24页
昆明理工大学WEB服务与分布式计算期末报告记录2.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

昆明理工大学WEB服务与分布式计算期末报告记录2.docx

《昆明理工大学WEB服务与分布式计算期末报告记录2.docx》由会员分享,可在线阅读,更多相关《昆明理工大学WEB服务与分布式计算期末报告记录2.docx(24页珍藏版)》请在冰豆网上搜索。

昆明理工大学WEB服务与分布式计算期末报告记录2.docx

昆明理工大学WEB服务与分布式计算期末报告记录2

昆明理工大学WEB服务与分布式计算期末报告记录2

 

 

————————————————————————————————作者:

————————————————————————————————日期:

 

课程报告

 

课程名称:

WEB服务与分布计算

设计题目:

基于Lucene全文检索系统

学院:

信息工程与自动化学院

专业:

计算机科学与技术

年级:

2012级

学生姓名:

邹华宇(201210405204)

指导教师:

王红斌

日期:

2015年6月16日

教务处制

 

期末考查结果评定

 

评分项目

分值

得分

报告条理清晰,内容详实,体会深刻

40

报告格式符合规范

10

程序符合要求

40

界面美观,功能有扩充

10

评语:

成绩:

指导教师签字:

评定日期:

年月日

1需求分析……………………………………………………………4

1.1系统背景介绍……………………………………………………………4

1.2功能需求分析……………………………………………………………4

2Lucene框架结构分析……………………………………………………………4

2.1系统功能结构……………………………………………………………4

2.2系统流程图……………………………………………………………4

2.3开发及运行环境……………………………………………………………4

3Lucene平台搭建……………………………………………………………4

4系统实现………………………………………………………………………10

5总结…………………………………………………………………12

1.需求分析

1.1系统背景介绍

Lucene是apache软件基金会4jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。

Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。

Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。

Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。

在Java开发环境里Lucene是一个成熟的免费开源工具。

作为一个全文搜索引擎,lucene具有以下突出优点:

(1)索引文件格式独立于应用平台。

Lucene定义了一套以8位字节为基础的索引文件格式,使得兼容系统或者不同平台的应用能够共享建立的索引文件。

(2)在传统全文检索引擎的倒排索引的基础上,实现了分块索引,能够针对新的文件建立小文件索引,提升索引速度。

然后通过与原有索引的合并,达到优化的目的。

(3)优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能。

(4)设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式,只需要实现文本分析的接口。

(5)内置一套强大的查询引擎,用户无需自己编写代码即使系统可获得强大的查询能力,Lucene的查询实现中默认实现了布尔操作、模糊查询(FuzzySearch)、分组查询等等。

1.2功能需求分析

本地文献信息检索是获取知识的捷径。

掌握文献信息检索方法与技能,可

以帮助人们快、准、全地获取所需知识,最大限度地节省查找时间,使文献信息得以充分的利用。

本程序的开发基于lucene的基础进行开发,在对本地文件进行文件名搜索的同时,能够更准确的识别文件内容与所搜索关键词的具体相关性。

搜索的目的是为了在大量的信息中发现自己感兴趣的信息。

但是,当有了足够的资料(比如网页、Word文档、Pdf文档,或数据库中的资料等)之后,并不能立即开始搜索,在此之前,必须先对信息建立索引。

所谓全文检索的核心就是索引,索引就是指将原始数据处理成一个高效的交叉引用的查找结构以便于快速的查找。

为了快速搜索大量的文本,你必须首先索引那个文本然后把它转化为一个可以让你快速搜索的格式,除去缓慢的顺序地扫描过程。

建立索引,就是对待搜索的信息进行一定的分析,并将分析结果按照一定的组织方式存储起来,通常将这些结果存储在文件中。

存储分析结果的文件的集合就是索引。

在查询时,先从索引中查找,由于索引是按照一定的结构组织的,所以查询的速度非常快。

2.Lucene框架结构分析

2.1系统功能结构

本地搜索程序的实现,需要lucene作为设计核心,lucene只关注文本的索引和搜索,Luncene的架构设计如图:

Lucene功能强大,但从根本上说,主要包括两块:

文本内容经切词后索引入库和根据查询条件返回结果。

查询逻辑:

查询者输入查询条件,条件之间可以通过特定运算符进行运算,比如查询希望查询到与“中国”和“北京”相关的记录,但不希望结果中包括“海淀区中关村”,于是输入条件为“中国+北京-海淀区中关村”;查询条件被传达到查询分析器中,分析器将将对“中国+北京-海淀区中关村”进行分析,首先分析器解析字符串的连接符,即这里的加号和减号,然后对每个词进行切词,一般最小的词元是两个汉字,则中国和北京两个词不必再切分,但对海淀区中关村需要切分,假设根据切词算法,把该词切分为“海淀区”和“中关村”两部分,则最后得到的查询条件可以表示为:

“中国”AND“北京”ANDNOT(“海淀区”AND“中关村”)。

查询器根据这个条件遍历索引树,得到查询结果,并返回结果集,返回的结果集类似于JDBC中的ResultSet。

将返回的结果集显示在查询结果页面,当点击某一条内容时,可以链接到原始网页,也可以打开全文检索库中存储的网页内容。

入库逻辑:

入库者定义到库中文档的结构,比如需要把网站内容加载到全文检索库,让用户通过“站内检索”搜索到相关的网页内容。

入库文档结构与关系型数据库中的表结构类似,每个入库的文档由多个字段构成,假设这里需要入库的网站内容包括如下字段:

文章标题、作者、发布时间、原文链接、正文内容(一般作为网页快照)。

包含N个字段的文档(DOCUMENT)在真正入库前需要经过切词(或分词)索引,切词的规则由语言分析器(ANALYZER)完成。

切分后的“单词”被注册到索引树上,供查询时用,另外也需要把其它不需要索引的内容入库,所有这些是文件操作均由STORAGE完成。

Lucene倒排索引原理

假设有两篇文章1和2

文章1的内容为:

TomlivesinGuangzhou,IliveinGuangzhoutoo.

文章2的内容为:

HeoncelivedinShanghai.

经过分词处理后

文章1的所有关键词为:

[tom][live][guangzhou][i][live][guangzhou]

文章2的所有关键词为:

[he][live][shanghai]

加上“出现频率”和“出现位置”信息后,我们的索引结构为:

 

非结构化数据中所存储的信息是每个文件包含哪些字符串,也即已知文件,欲求字符串相对容易,也即是从文件到字符串的映射。

而我们想搜索的信息是哪些文件包含此字符串,也即已知字符串,欲求文件,也即从字符串到文件的映射。

两者恰恰相反。

于是如果索引总能够保存从字符串到文件的映射,则会大大提高搜索速度。

由于从字符串到文件的映射是文件到字符串映射的反向过程,于是保存这种信息的索引称为反向索引。

反向索引的所保存的信息一般如下:

假设我的文档集合里面有100篇文档,为了方便表示,我们为文档编号从1到100,得到下面的结构:

左边保存的是一系列字符串,称为词典。

每个字符串都指向包含此字符串的文档(Document)链表,此文档链表称为倒排表 (PostingList)。

有了索引,便使保存的信息和要搜索的信息一致,可以大大加快搜索的速度。

 

2.2系统流程图

2.2.1索引创建(Indexing)

全文检索的索引创建过程一般有以下几步:

第一步:

一些要索引的原文档(Document)。

第二步:

将原文档传给分词器(Tokenizer)。

分词器(Tokenizer)会做以下几件事情(此过程称为Tokenize) :

1. 将文档分成一个一个单独的单词。

2. 去除标点符号。

3. 去除停词

所谓停词就是一种语言中最普通的一些单词,由于没有特别的意义,因而大多数情况下不能成为搜索的关键词,因而创建索引时,这种词会被去掉而减少索引的大小。

英语中停词(Stopword)如:

“the”,“a”,“this”等。

对于每一种语言的分词组件(Tokenizer),都有一个停词(stopword)集合经过分词(Tokenizer)后得到的结果称为词元(Token).

第三步:

将得到的词元(Token)传给语言处理组件(LinguisticProcessor)。

语言处理组件(linguisticprocessor)主要是对得到的词元(Token)做一些同语言相关的处理。

对于英语,语言处理组件(LinguisticProcessor) 一般做以下几点:

1. 变为小写(Lowercase) 。

2. 将单词缩减为词根形式,这种操作称为:

stemming.

3. 将单词转变为词根形式,这种操作称为:

lemmatization.

Stemming和lemmatization的异同:

相同之处:

Stemming和lemmatization都要使词汇成为词根形式。

两者的方式不同:

Stemming采用的是“缩减”的方式Lemmatization采用的是“转变”的方式.两者的算法不同:

Stemming主要是采取某种固定的算法来做这种缩减Lemmatization主要是采用保存某种字典的方式做这种转变。

Stemming和lemmatization不是互斥关系,是有交集的.语言处理组件(linguisticprocessor)的结果称为词(Term).也正是因为有语言处理的步骤,才能使搜索drove,而drive也能被搜索出来。

第四步:

将得到的词(Term)传给索引组件(Indexer)。

索引组件(Indexer)主要做以下几件事情:

1.利用得到的词(Term)创建一个字典。

2. 对字典按字母顺序进行排序。

 

2.1.2搜索索引(Search)

第一步:

用户输入查询语句。

查询语句同我们普通的语言一样,也是有一定语法的。

不同的查询语句有不同的语法,如SQL语句就有一定的语法。

查询语句的语法根据全文检索系统的实现而不同。

最基本的有比如:

AND,OR,NOT等。

举个例子,用户输入语句:

luceneANDlearnedNOThadoop。

说明用户想找一个包含lucene和learned然而不包括hadoop的文档。

第二步:

对查询语句进行词法分析,语法分析,及语言处理。

1.词法分析主要用来识别单词和关键字。

如上述例子中,经过词法分析,得到单词有lucene,learned,hadoop,关键字有AND,NOT。

如果在词法分析中发现不合法的关键字,则会出现错误。

如luceneAMDlearned,其中由于AND拼错,导致AMD作为一个普通的单词参与查询。

2.语法分析主要是根据查询语句的语法规则来形成一棵语法树。

如果发现查询语句不满足语法规则,则会报错。

如luceneNOTANDlearned,则会出错。

3.语言处理同索引过程中的语言处理几乎相同。

第三步:

搜索索引,得到符合语法树的文档

首先,在反向索引表中,分别找出包含lucene,learn,hadoop的文档链表。

其次,对包含lucene,learn的链表进行合并操作,得到既包含lucene又包含learn的文档链表。

然后,将此链表与hadoop的文档链表进行差操作,去除包含hadoop的文档,从而得到既包含lucene又包含learn而且不包含hadoop的文档链表.此文档链表就是我们要找的文档。

第四步:

根据得到的文档和查询语句的相关性,对结果进行排序

虽然在上一步,我们得到了想要的文档,然而对于查询结果应该按照与查询语句的相关性进行排序,越相关者越靠前

2.3开发及运行环境

本次报告在MyEclipseProfessional2013上搭建luncene平台实现全文检索

jdk使用1.6

lucene版本为4.0

 

3.Lucene平台搭建

Lucene的系统由基础结构封装、索引核心、对外接口三大部分组成。

其中直接操作索引文件的索引核心又是系统的重点。

IndexWriter是在索引过程中的中心组件。

IndexWriter这个类创建一个新的索引并且添加文档到一个已有的索引中。

Directory类代表一个Lucene索引的位置。

它是一个抽象类。

其中的两个实现类:

FSDirectory,它表示一个存储在文件系统中的索引的位置。

RAMDirectory,它表示一个存储在内存当中的索引的位置Analyzer在一个文档被索引之前,首先需要对文档内容进行分词处理,并且而剔除一些冗余的词句(例如:

a,the,they等),这部分工作就是由Analyzer来做的。

Document文档类似数据库中的一条记录,可以由好几个字段(Field)组成,并且字段可以套用不同的类型。

一个Field代表与这个文档相关的元数据。

元数据如作者、标题、主题、修改日期等等,分别做为文档的字段索引和存储。

Field对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个Field对象分别描述。

IndexSearcher是用来在建立好的索引上进行搜索的它只能以只读的方式打开一个索引,所以可以有多个IndexSearcher的实例在一个索引上进行操作。

第一个,Lucene-core-4.0.0.jar,其中包括了常用的文档,索引,搜索,存储等相关核心代码。

第二个,Lucene-analyzers-common-4.0.0.jar,这里面包含了各种语言的词法分析器,用于对文件内容进行关键字切分,提取。

第三个,Lucene-highlighter-4.0.0.jar,这个jar包主要用于搜索出的内容高亮显示。

第四个和第五个,Lucene-queryparser-4.0.0.jar,提供了搜索相关的代码,用于各种搜索,比如模糊搜索,范围搜索,等等。

两个调用office文档的扩展包:

4.系统实现

4.1建立luceneDataluceneIndex的地址字符

privatestaticStringINDEX_DIR="luceneIndex";

privatestaticStringDATA_DIR="luceneData";

4.2创建索引管理器

publicIndexManagergetManager(){

if(indexManager==null){

this.indexManager=newIndexManager();

}

returnindexManager;

}

4.3创建当前文件目录的索引

publicstaticbooleancreateIndex(Stringpath){

Datedate1=newDate();

ListfileList=getFileList(path);

for(Filefile:

fileList){

content="";

//获取文件后缀

Stringtype=file.getName().substring(file.getName().lastIndexOf(".")+1);

if("txt".equalsIgnoreCase(type)){

content+=txt2String(file);

}elseif("doc".equalsIgnoreCase(type)){

content+=doc2String(file);

}elseif("xls".equalsIgnoreCase(type)){

content+=xls2String(file);

}elseif("html".equalsIgnoreCase(type)){

content+=html2String(file);

}

System.out.println("name:

"+file.getName());

System.out.println("path:

"+file.getPath());

System.out.println();

try{

analyzer=newStandardAnalyzer(Version.LUCENE_CURRENT);

directory=FSDirectory.open(newFile(INDEX_DIR));

FileindexFile=newFile(INDEX_DIR);

if(!

indexFile.exists()){

indexFile.mkdirs();

}

IndexWriterConfigconfig=newIndexWriterConfig(Version.LUCENE_CURRENT,analyzer);

indexWriter=newIndexWriter(directory,config);

Documentdocument=newDocument();

document.add(newTextField("filename",file.getName(),Store.YES));

document.add(newTextField("content",content,Store.YES));

document.add(newTextField("path",file.getPath(),Store.YES));

indexWriter.addDocument(document);

indexWmit();

closeWriter();

}catch(Exceptione){

e.printStackTrace();

}

content="";

}

Datedate2=newDate();

System.out.println("创建索引-----耗时:

"+(date2.getTime()-date1.getTime())+"ms\n");

returntrue;

}

4.4实现代码读取数据文件内容

BufferedReaderbr=newBufferedReader(newFileReader(file));

Strings=null;

while((s=br.readLine())!

=null){result=result+"\n"+s;

}

br.close();

}catch(Exceptione){e.printStackTrace()returnresult;}

try{FileInputStreamfis=newFileInputStream(file);HWPFDocumentdoc=newHWPFDocument(fis);

Rangerang=doc.getRange();

result+=rang.text();

fis.close();}catch(Exceptione){e.printStackTrace()}

FileInputStreamfis=newFileInputStream(file);

StringBuildersb=newStringBuilder();

jxl.Workbookrwb=Workbook.getWorkbook(fis);

Sheet[]sheet=rwb.getSheets();

for(inti=0;i

Sheetrs=rwb.getSheet(i);

for(intj=0;j

Cell[]cells=rs.getRow(j);

for(intk=0;k

sb.append(cells[k].getContents());}}fis.close();

4.5查找索引

Datedate1=newDate();

try{

directory=FSDirectory.open(newFile(INDEX_DIR));

analyzer=newStandardAnalyzer(Version.LUCENE_CURRENT);

DirectoryReaderireader=DirectoryReader.open(directory);

IndexSearcherisearcher=newIndexSearcher(ireader);

QueryParserparser=newQueryParser(Version.LUCENE_CURRENT,"content",analyzer);

Queryquery=parser.parse(text);

ScoreDoc[]hits=isearcher.search(query,null,1000).scoreDocs;

for(inti=0;i

DocumenthitDoc=isearcher.doc(hits[i].doc);

System.out.println("____________________________");

System.out.println(hitDoc.get("filename"));

System.out.println(hitDoc.get("content"));

System.out.println(hitDoc.get("path"));

System.out.println("____________________________");

}

ireader.close();

directory.close();

}catch(Exceptione){

e.printStackTrace();

}

Datedate2=newDate();

System.out.println("查看索引-----耗时:

"+(date2.getTime()

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 社交礼仪

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1