Lucene技术总结Word文档下载推荐.docx
《Lucene技术总结Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Lucene技术总结Word文档下载推荐.docx(23页珍藏版)》请在冰豆网上搜索。
指不定长或无固定格式的数据,如邮件,word文档等。
对结构化数据的搜索,我们一般用到数据库比较多。
那对于全文数据的搜索呢?
我们需要针对全文数据制定全文搜索的方式,其中像lucene这样,先建立索引,再对索引进行搜索就是其中的一种。
Lucene是一个基于java的全文索引引擎工具包,它提供了各种借口,可以方便的嵌入到各种应用中,通过对接口的实现满足我们全文索引或者检索功能。
在对非结构化数据索引之前,我们需要先将数据进行分词处理,对于英文分词比较简单,一个空格间隔就是一个单词,而对于中文,我们如何将中文的词提取出来再进行索引难度就比较大了。
Lucene提供了多种语言分析器,在本文档的第四节中,我们将会对lucene分词技术做详细的讲解。
在对文字进行关键字提取之后,下一步就需要对内容进行索引了。
索引是通过document存储的,document可以设定多个field字段,根据需要按照规则索引或者存储字段。
索引同数据库的索引一样是有序的,因此lucene可以很高效的搜索信息。
索引文件记录了词和词在文件中的偏移量。
搜索的时候,语言分析器,查询分析器,甚至搜索器(Searcher)都是提供了抽象的接口,可以根据需要进行定制。
搜索结果返回的是Hits对象,可以通过它提取到查询返回的索引(也是通过document对象返回的),我们可以根据需要通过java代码将它转换为所需的对象。
三、简单的案例
这一章节给出一个简单的案例,希望大家通过这个案例对lucene有个初步的认识。
案例的源代码并不是知识库的搜索源代码,而是我从网上找的部分代码。
1.如下是创建索引的实现:
publicstaticvoidcreateTxtFileIndex(){
//设置索引地址
FileindexDir=newFile("
D:
\\luceneIndex"
);
//设置数据地址
FiledataDir=newFile("
\\luceneData"
//建立分词
AnalyzerluceneAnalyzer=newStandardAnalyzer();
//取得目录下所有Files
File[]dataFiles=dataDir.listFiles();
//建立indexWriteindexWrite主要作用是添加索引
IndexWriterindexWriter=newIndexWriter(indexDir,luceneAnalyzer,true);
//循环文件
for(inti=0;
i<
dataFiles.length;
i++){
//取出txt后缀的文档
if(dataFiles[i].isFile()&
&
dataFiles[i].getName().endsWith("
.txt"
)){
System.out.println("
Indexingfile"
+dataFiles[i].getCanonicalPath());
//新建一个Document
Documentdocument=newDocument();
//读取数据
ReadertxtReader=newFileReader(dataFiles[i]);
//Document添加path
document.add(newField("
path"
dataFiles[i].getCanonicalPath(),Field.Store.YES,Field.Index.UN_TOKENIZED));
//Document添加正文
contents"
txtReader));
//添加索引
indexWriter.addDocument(document);
}
//优化索引
indexWriter.optimize();
//关闭indexWriter
indexWriter.close();
}
2.搜索的代码实现如下:
publicstaticvoidTxtFileSearcher(){
Loggerlogger=Logger.getLogger(TxtFileSearcher.class);
//要查询的词组
StringqueryStr="
com.log4j.test.TestLog.main"
;
//索引地址
FileindexDir=newFile("
//取得索引字典
FSDirectorydirectory=FSDirectory.getDirectory(indexDir,false);
//建立查询
IndexSearchersearcher=newIndexSearcher(directory);
//查询的索引地址是否存在
if(!
indexDir.exists()){
System.out.println("
TheLuceneindexisnotexist"
return;
//建立term查询docuemnt中contents中的内容(内容要转为大字)
Termterm=newTerm("
queryStr.toLowerCase());
//进行查询
TermQueryluceneQuery=newTermQuery(term);
//生成结果
Hitshits=searcher.search(luceneQuery);
hits.length();
//取得结果中的dowuemnt
Documentdocument=hits.doc(i);
//取得返回的path属性
File:
"
+document.get("
));
四、中文分词
分析器作用于索引和文本之间,索引要进入索引库的文本资源都要先通过分析器的分析(切词和过滤),以便确保索引库中的索引内容的正确性。
如果不经过分析器分析就把文本内容存入索引中,那么会引起索引内容数据的不一致,也会降低索引的效率,进而影响整个搜索引擎的性能。
中文分词的方式有如下几种:
1.单字分词
单字分词,顾名思义,就是按照中文一个字一个字地进行分词。
如:
我们是中国人,效果:
我/们/是/中/国/人。
2.二分法
二分法,就是按两个字进行切分。
我们/们是/是中/中国/国人。
3.词库分词
词库分词,就是按某种算法构造词然后去匹配已建好的词库集合,如果匹配到就切分出来成为词语。
通常词库分词被认为是最理想的中文分词算法如:
我们是中国人,通成效果为:
我们/是/中国/中国人。
针对不同的分词方式,Lucene提供了多种语言分析器,以下我简单的给大家介绍几种比较常用的:
1.StandardAnalyzer
StandardAnalyzer即标准分析器,是通过单字分词的方式进行切分的,它是最容易使用也是使用最频繁的一种Analyzer,内部使用了Lucene自带的几种分词器和过滤器,来完成该标准分析器的功能效果。
StandardAnalyzer分析器对中文的处理:
将会把中文文本,一个字一个字的进行分词,也表明该分析器对中文的支持不太好。
我们是中国人。
切分后的效果:
如果实际中使用该分析器对中文创建索引,那么带来的缺点是使索引的内容过于庞大等,不便于建立索引和搜索效率的提高。
对于山东农信知识库系统,由于搜索机制的需求,我们使用的就是标准分析器。
2.CJKAnalyzer
CJKAnalyzer是通过二分法进行分词的。
对中文汉字,每两个字作为一个词条。
效果:
其实,CJKAnalyzer分析器在对中文分词方面比StandardAnalyzer分析器要好一点。
因为根据中文的习惯,包括搜索的时候键入关键字的习惯,中文的词(大于一个汉字)比单个汉字的频率应该高一些。
但是,在设置相同的过滤词条文本以后,CJKAnalyzer分析器的缺点就是产生了冗余会比较大,相对于StandardAnalyzer分析器来说。
使用StandardAnalyzer分析器可以考虑在以字作为词条时,通过过滤词条文本来优化分词。
而CJKAnalyzer分析器在给定的过滤词条文本的基础之上,获取有用的词条实际是一个在具有一定中文语言习惯的基础上能够获得最高的期望。
3.IKAnalyzer
IKAnalyzer基于lucene2.0版本API开发,实现了以词典分词为基础的正反向全切分算法,是LuceneAnalyzer接口的实现,我比较推荐使用IKAnalyzer,比较符合汉语的语法和习惯,而且效率很高。
例子:
据路透社报道,印度尼西亚社会事务部一官员星期二(29日)表示,日惹市附近当地时间27日晨5时53分发生的里氏6.2级地震已经造成至少5427人死亡?
20000余人受伤,近20万人无家可归。
切分后的结果如下:
1-4=路透社
4-6=报道
7-12=印度尼西亚
12-14=社会
14-17=事务部
17-18=一
18-20=官员
20-23=星期二
24-27=29日
28-30=表示
31-34=日惹市
34-36=附近
36-40=当地时间
40-43=27日
43-44=晨
44-46=5时
46-49=53分
48-50=分发
49-51=发生
52-54=里氏
54-58=6.2级
58-60=地震
60-62=已经
62-64=造成
64-