搜索引擎知识汇总.docx
- 文档编号:3843965
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:14
- 大小:51.95KB
搜索引擎知识汇总.docx
《搜索引擎知识汇总.docx》由会员分享,可在线阅读,更多相关《搜索引擎知识汇总.docx(14页珍藏版)》请在冰豆网上搜索。
搜索引擎知识汇总
1Lucene级别:
初级
朋周登(zhoudengpeng@),软件工程师
2006年4月20日
本文首先介绍了Lucene的一些基本概念,然后开发了一个应用程序演示了利用Lucene建立索引并在该索引上进行搜索的过程。
Lucene简介
Lucene是一个基于Java的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。
Lucene目前是ApacheJakarta家族中的一个开源项目。
也是目前最为流行的基于Java开源全文检索工具包。
目前已经有很多应用程序的搜索功能是基于Lucene的,比如Eclipse的帮助系统的搜索功能。
Lucene能够为文本类型的数据建立索引,所以你只要能把你要索引的数据格式转化的文本的,Lucene就能对你的文档进行索引和搜索。
比如你要对一些HTML文档,PDF文档进行索引的话你就首先需要把HTML文档和PDF文档转化成文本格式的,然后将转化后的内容交给Lucene进行索引,然后把创建好的索引文件保存到磁盘或者内存中,最后根据用户输入的查询条件在索引文件上进行查询。
不指定要索引的文档的格式也使Lucene能够几乎适用于所有的搜索应用程序。
图1表示了搜索应用程序和Lucene之间的关系,也反映了利用Lucene构建搜索应用程序的流程:
图1.搜索应用程序和Lucene之间的关系
s
索引和搜索
索引是现代搜索引擎的核心,建立索引的过程就是把源数据处理成非常方便查询的索引文件的过程。
为什么索引这么重要呢,试想你现在要在大量的文档中搜索含有某个关键词的文档,那么如果不建立索引的话你就需要把这些文档顺序的读入内存,然后检查这个文章中是不是含有要查找的关键词,这样的话就会耗费非常多的时间,想想搜索引擎可是在毫秒级的时间内查找出要搜索的结果的。
这就是由于建立了索引的原因,你可以把索引想象成这样一种数据结构,他能够使你快速的随机访问存储在索引中的关键词,进而找到该关键词所关联的文档。
Lucene采用的是一种称为反向索引(invertedindex)的机制。
反向索引就是说我们维护了一个词/短语表,对于这个表中的每个词/短语,都有一个链表描述了有哪些文档包含了这个词/短语。
这样在用户输入查询条件的时候,就能非常快的得到搜索结果。
我们将在本系列文章的第二部分详细介绍Lucene的索引机制,由于Lucene提供了简单易用的API,所以即使读者刚开始对全文本进行索引的机制并不太了解,也可以非常容易的使用Lucene对你的文档实现索引。
对文档建立好索引后,就可以在这些索引上面进行搜索了。
搜索引擎首先会对搜索的关键词进行解析,然后再在建立好的索引上面进行查找,最终返回和用户输入的关键词相关联的文档。
Lucene软件包分析
Lucene软件包的发布形式是一个JAR文件,下面我们分析一下这个JAR文件里面的主要的JAVA包,使读者对之有个初步的了解。
Package:
org.apache.lucene.document
这个包提供了一些为封装要索引的文档所需要的类,比如Document,Field。
这样,每一个文档最终被封装成了一个Document对象。
Package:
org.apache.lucene.analysis
这个包主要功能是对文档进行分词,因为文档在建立索引之前必须要进行分词,所以这个包的作用可以看成是为建立索引做准备工作。
Package:
org.apache.lucene.index
这个包提供了一些类来协助创建索引以及对创建好的索引进行更新。
这里面有两个基础的类:
IndexWriter和IndexReader,其中IndexWriter是用来创建索引并添加文档到索引中的,IndexReader是用来删除索引中的文档的。
Package:
org.apache.lucene.search
这个包提供了对在建立好的索引上进行搜索所需要的类。
比如IndexSearcher和Hits,IndexSearcher定义了在指定的索引上进行搜索的方法,Hits用来保存搜索得到的结果。
回页首
一个简单的搜索应用程序
假设我们的电脑的目录中含有很多文本文档,我们需要查找哪些文档含有某个关键词。
为了实现这种功能,我们首先利用Lucene对这个目录中的文档建立索引,然后在建立好的索引中搜索我们所要查找的文档。
通过这个例子读者会对如何利用Lucene构建自己的搜索应用程序有个比较清楚的认识。
回页首
建立索引
为了对文档进行索引,Lucene提供了五个基础的类,他们分别是Document,Field,IndexWriter,Analyzer,Directory。
下面我们分别介绍一下这五个类的用途:
Document
Document是用来描述文档的,这里的文档可以指一个HTML页面,一封电子邮件,或者是一个文本文件。
一个Document对象由多个Field对象组成的。
可以把一个Document对象想象成数据库中的一个记录,而每个Field对象就是记录的一个字段。
Field
Field对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个Field对象分别描述。
Analyzer
在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由Analyzer来做的。
Analyzer类是一个抽象类,它有多个实现。
针对不同的语言和应用需要选择适合的Analyzer。
Analyzer把分词后的内容交给IndexWriter来建立索引。
IndexWriter
IndexWriter是Lucene用来创建索引的一个核心的类,他的作用是把一个个的Document对象加到索引中来。
Directory
这个类代表了Lucene的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是FSDirectory,它表示一个存储在文件系统中的索引的位置。
第二个是RAMDirectory,它表示一个存储在内存当中的索引的位置。
熟悉了建立索引所需要的这些类后,我们就开始对某个目录下面的文本文件建立索引了,清单1给出了对某个目录下的文本文件建立索引的源代码。
清单1.对文本文件建立索引
packageTestLucene;
importjava.io.File;
importjava.io.FileReader;
importjava.io.Reader;
importjava.util.Date;
importorg.apache.lucene.analysis.Analyzer;
importorg.apache.lucene.analysis.standard.StandardAnalyzer;
importorg.apache.lucene.document.Document;
importorg.apache.lucene.document.Field;
importorg.apache.lucene.index.IndexWriter;
/**
*ThisclassdemonstratetheprocessofcreatingindexwithLucene
*fortextfiles
*/
publicclassTxtFileIndexer{
publicstaticvoidmain(String[]args)throwsException{
//indexDiristhedirectorythathostsLucene'sindexfiles
FileindexDir=newFile("D:
\\luceneIndex");
//dataDiristhedirectorythathoststhetextfilesthattobeindexed
FiledataDir=newFile("D:
\\luceneData");
AnalyzerluceneAnalyzer=newStandardAnalyzer();
File[]dataFiles=dataDir.listFiles();
IndexWriterindexWriter=newIndexWriter(indexDir,luceneAnalyzer,true);
longstartTime=newDate().getTime();
for(inti=0;i if(dataFiles[i].isFile()&&dataFiles[i].getName().endsWith(".txt")){ System.out.println("Indexingfile"+dataFiles[i].getCanonicalPath()); Documentdocument=newDocument(); ReadertxtReader=newFileReader(dataFiles[i]); document.add(Field.Text("path",dataFiles[i].getCanonicalPath())); document.add(Field.Text("contents",txtReader)); indexWriter.addDocument(document); } } indexWriter.optimize(); indexWriter.close(); longendTime=newDate().getTime(); System.out.println("Ittakes"+(endTime-startTime) +"millisecondstocreateindexforthefilesindirectory" +dataDir.getPath()); } } 在清单1中,我们注意到类IndexWriter的构造函数需要三个参数,第一个参数指定了所创建的索引要存放的位置,他可以是一个File对象,也可以是一个FSDirectory对象或者RAMDirectory对象。 第二个参数指定了Analyzer类的一个实现,也就是指定这个索引是用哪个分词器对文挡内容进行分词。 第三个参数是一个布尔型的变量,如果为true的话就代表创建一个新的索引,为false的话就代表在原来索引的基础上进行操作。 接着程序遍历了目录下面的所有文本文档,并为每一个文本文档创建了一个Document对象。 然后把文本文档的两个属性: 路径和内容加入到了两个Field对象中,接着在把这两个Field对象加入到Document对象中,最后把这个文档用IndexWriter类的add方法加入到索引中去。 这样我们便完成了索引的创建。 接下来我们进入在建立好的索引上进行搜索的部分。 回页首 搜索文档 利用Lucene进行搜索就像建立索引一样也是非常方便的。 在上面一部分中,我们已经为一个目录下的文本文档建立好了索引,现在我们就要在这个索引上进行搜索以找到包含某个关键词或短语的文档。 Lucene提供了几个基础的类来完成这个过程,它们分别是呢IndexSearcher,Term,Query,TermQuery,Hits.下面我们分别介绍这几个类的功能。 Query 这是一个抽象类,他有多个实现,比如TermQuery,BooleanQuery,PrefixQuery.这个类的目的是把用户输入的查询字符串封装成Lucene能够识别的Query。 Term Term是搜索的基本单位,一个Term对象有两个String类型的域组成。 生成一个Term对象可以有如下一条语句来完成: Termterm=newTerm(“fieldName”,”queryWord”);其中第一个参数代表了要在文档的哪一个Field上进行查找,第二个参数代表了要查询的关键词。 TermQuery TermQuery是抽象类Query的一个子类,它同时也是Lucene支持的最为基本的一个查询类。 生成一个TermQuery对象由如下语句完成: TermQuerytermQuery=newTermQuery(newTerm(“fieldName”,”queryWord”));它的构造函数只接受一个参数,那就是一个Term对象。 IndexSearcher IndexSearcher是用来在建立好的索引上进行搜索的。 它只能以只读的方式打开一个索引,所以可以有多个IndexSearcher的实例在一个索引上进行操作。 Hits Hits是用来保存搜索的结果的。 介绍完这些搜索所必须的类之后,我们就开始在之前所建立的索引上进行搜索了,清单2给出了完成搜索功能所需要的代码。 清单2: 在建立好的索引上进行搜索 packageTestLucene; importjava.io.File; importorg.apache.lucene.document.Document; importorg.apache.lucene.index.Term; importorg.apache.lucene.search.Hits; importorg.apache.lucene.search.IndexSearcher; importorg.apache.lucene.search.TermQuery; importorg.apache.lucene.store.FSDirectory; /** *Thisclassisusedtodemonstratethe *processofsearchingonanexisting *Luceneindex * */ publicclassTxtFileSearcher{ publicstaticvoidmain(String[]args)throwsException{ StringqueryStr="lucene"; //ThisisthedirectorythathoststheLuceneindex FileindexDir=newFile("D: \\luceneIndex"); FSDirectorydirectory=FSDirectory.getDirectory(indexDir,false); IndexSearchersearcher=newIndexSearcher(directory); if(! indexDir.exists()){ System.out.println("TheLuceneindexisnotexist"); return; } Termterm=newTerm("contents",queryStr.toLowerCase()); TermQueryluceneQuery=newTermQuery(term); Hitshits=searcher.search(luceneQuery); for(inti=0;i Documentdocument=hits.doc(i); System.out.println("File: "+document.get("path")); } } } 在清单2中,类IndexSearcher的构造函数接受一个类型为Directory的对象,Directory是一个抽象类,它目前有两个子类: FSDirctory和RAMDirectory.我们的程序中传入了一个FSDirctory对象作为其参数,代表了一个存储在磁盘上的索引的位置。 构造函数执行完成后,代表了这个IndexSearcher以只读的方式打开了一个索引。 然后我们程序构造了一个Term对象,通过这个Term对象,我们指定了要在文档的内容中搜索包含关键词”lucene”的文档。 接着利用这个Term对象构造出TermQuery对象并把这个TermQuery对象传入到IndexSearcher的search方法中进行查询,返回的结果保存在Hits对象中。 最后我们用了一个循环语句把搜索到的文档的路径都打印了出来。 好了,我们的搜索应用程序已经开发完毕,怎么样,利用Lucene开发搜索应用程序是不是很简单。 回页首 总结 本文首先介绍了Lucene的一些基本概念,然后开发了一个应用程序演示了利用Lucene建立索引并在该索引上进行搜索的过程。 希望本文能够为学习Lucene的读者提供帮助。 关于作者 周登朋,软件工程师,上海交通大学研究生,对Java技术以及信息检索技术很感兴趣。 您可以通过zhoudengpeng@与他联系。 S 2使用solr搭建你的全文检索 Solr是一个可供企业使用的、基于Lucene的开箱即用的搜索服务器。 对Lucene不熟? 那么建议先看看下面两篇文档: 实战Lucene,第1部分: 初识Lucene: 用Lucene加速Web搜索应用程序的开发: 一、 solr介绍 solr是基于LuceneJava搜索库的企业级全文搜索引擎,目前是apache的一个项目。 它的官方网址在http: //lucene.apache.org/solr/。 solr需要运行在一个servlet容器里,例如tomcat5.5。 solr在lucene的上层提供了一个基于HTTP/XML的WebServices,我们的应用需要通过这个服务与solr进行交互。 二、 solr安装和配置 关于solr的安装和配置,这里也有两篇非常好的文档,作者同时也是LuceneJava项目的提交人和发言人: 使用ApacheSolr实现更加灵巧的搜索: 下面主要说说需要注意的地方。 Solr的安装非常简单,下载solr的zip包后解压缩将dist目录下的war文件改名为solr.war直接复制到tomcat5.5的webapps目录即可。 注意一定要设置solr的主位置。 有三种方法。 我采用的是在tomcat里配置java: comp/env/solr/home的一个JNDI指向solr的主目录(example目录下),建立/tomcat55/conf/Catalina/localhost/solr.xml文件。 /solr.war" debug="0" crossContext="true" > /solr/solr" override="true" /> 观察这个指定的solr主位置,里面存在两个文件夹: conf和data。 其中conf里存放了对solr而言最为重要的两个配置文件schema.xml和solrconfig.xml。 data则用于存放索引文件。 schema.xml主要包括types、fields和其他的一些缺省设置。 solrconfig.xml用来配置Solr的一些系统属性,例如与索引和查询处理有关的一些常见的配置选项,以及缓存、扩展等等。 上面的文档对这两个文件有比较详细的说明,非常容易上手。 注意到schema.xml里有一个 的配置,这里将url字段作为索引文档的唯一标识符,非常重要。 三、 加入中文分词 对全文检索而言,中文分词非常的重要,这里采用了qieqie庖丁分词(非常不错: ))。 集成非常的容易,我下载的是2.0.4-alpha2版本,其中它支持最多切分和按最大切分。 创建自己的一个中文TokenizerFactory继承自solr的BaseTokenizerFactory。 /** * Created by IntelliJ IDEA. * User: ronghao * Date: 2007-11-3 * Time: 14: 40: 59 * 中文切词 对庖丁切词的封装 */ public class ChineseTokenizerFactory extends BaseTokenizerFactory { /** * 最多切分 默认模式 */ public static final String MOST_WORDS_MODE = "most-words"; /** * 按最大切分 */ public static final String MAX_WORD_LENGTH_MODE = "max-word-length"; private String mode = null; public void setMode(String mode) { if (mode==null||MOST_WORDS_MODE.equalsIgnoreCase(mode) || "default".equalsIgnoreCase(mode)) { this.mode=MOST_WORDS_MODE; } else if (MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode)) { this.mode=MAX_WORD_LENGTH_MODE; } else {
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 搜索引擎 知识 汇总