lucene学习
- 格式:docx
- 大小:62.52 KB
- 文档页数:43
lucene学习
1.基本概念
信息检索(IR)是指文档搜索、文档内信息搜索或者文档相关的元数据搜索等操作。文档:用于搜索的内容部件。
词汇单元:即分词。词干提取器,如Snowball。
搜索质量主要由查准率(Preciion)和查全率(Recall)来衡量。[1]P13语法检查器:Lucene的contrib目录提供了两个模块完成此功能。
查询对象:Lucene提供了一个称之为查询解析器(QueryParer),用它可以根据通用查询语法将用户输入的文本处理成查询对象。
查询搜索:査询检索索引并返回与査询语句匹配的文档,结果返回时按照査询请求来排序。搜索查询组件涵盖了搜索引擎内部复杂的工作机制,Lucene正是如此,它为你完成这一切。倒排索引:invertedinde某
常见的搜索理论模型有如下3种。
■纯布尔模型(PureBooleanmodel)文档不管是否匹配查询请求,都不会被评分.在该模型下,匹配文档与评分不相关,也是无序的;一条查询仅获取所有匹配文档集合的一个子集。
■向量空间模型(Vectorpacemodel)
查询语句和文档都是高维空间的向
量模型,这里每一个独立的项都是一个维度。查询语句和文档之间的相关性或相似性由各自向量之间的距离计算得到. ■概率模型(Probabiliticmodel)在该模型中,采用全概率方法来计算文档和查询语句的匹配概率。
Lucene在实现上采用向量空间模型和纯布尔模型,并能针对具体搜索让你决定采用哪种模型。最后,Lucene返回的文档结果必须用比较经济的方式展现给用户。
搜索范围:涉及分布式搜索,ApacheLucene项目下的Solr和Nutch项目提供了对索引拆分和复制的支持,另Katta和Elaticearch。
1.1Lucene核心类概貌
执行简单的索引过程需要用到以下几个类:■Inde某Writer■Directory■Analyzer■Document■Field
Inde某Writer(写索引)是索引过程的核心组件。这个类负责创建新索引或者打
开已有索引,以及向索引中添加、删除或更新被索引文档的信息。可以把Inde某Writer看做这样一个对象:它为你提供针对索引文件的写人操作,但不能用于读取或搜索索引。Inde某Writer需要开辟一定空间来存储索引,该功能可以由Directory完成。
Directory类描述了Lucene索引的存放位置。它是一个抽象类,它的子类负
责具体指定索引的存储路径。在前面的Inde某er例子中,我们用FSDirectory.open方法来获取真实文件在文件系统的存储路径,然后将它们依次传递给Inde某Writer类构造方法。 文本文件在被索引之前,需要经过Analyzer(分析器)处理。Analyzer是由
Inde某Writer的构造方法来指定的,它负责从被索引文本文件中提取语汇单元,并提出剩下的无用信息。如果被索引内容不是纯文本文件,那就就需要先
将其转换为文本文档。
Document(文档)对象代表一些域(Field)的集合。你可以将Document对象
理解为虚拟文档——比如Web页面、E-mail信息或者文本文件——然后你可以从中取回大量数据。文档的域代表文档或者和文档相关的一些元数据。文档的数据源(比如数据库记录、Word文档、书中的某章节等)对于Lucene来说是无关紧要的。Lucene只处理从二进制文档中提取的以Field实例形式出现的文本。
索引中的每个文档都包含一个或多个不同命名的域,这些域包含在Field类
中。每个域都有一个域名和对应的域值,以及一组选项来精确控制Lucene索引操作各个域值。文档可能拥有不止一个同名的域。在这种情况下,域的值就按照索引操作顺序添加进去。在搜索时,所有域的文本就好像连接在一起,作为一个文本域来处理。
搜索操作:■Inde某Searcher■Term■Query■TermQuery■TopDoc
Inde某Searcher类用于搜索由Inde某Writer类创建的索引:这个类公开了几个 搜索方法,它是连接索引的中心环节。可以将Inde某Searcher类看做一个以只读方式打开索引的类。它需要利用Directory实例来掌控前期创建的索引,然后才能提供大量的搜索方法,其中一些方法在它的抽象父类Searcher中实现,最简单的搜索方法是将单个Query对象和inttopN计数作为该方法的参数,并返回一个TopDoc对象。
Directorydir=FSDirectory.open(newFile(\;Inde某Searcherearcher=newInde某Searcher(dir);
Queryq=newTermQuery(newTerm(\TopDochit-earcher.earch(q,10);earcher.cloe();
Term对象是搜索功能的基本单元。与Field对象类似,Term对象包含一对字
符串元素:域名和单词(或域文本值)。注意Term对象还与索引操作有关。然而,由于Term对象是由Lucene内部创建的,我们并不需要在索引阶段详细了解它们。在搜索过程中可以创建Term对象,并和TermQuery对象一起使用:
Queryq=newTermQuery(newTerm(\;TopDochit=earcher.earch(q,10);
Lucene含有许多具体的Query(查询)子类。到目前为止,我们谈到的只是
Lucene基本的Query子类:TermQuery类。其他的Query子类有:BooleanQuery、PhraeQuery、Prefi某Query、PhraePrefi某Query、TermRangeQuery、NumericRangeQuery、FilteredQuery和SpanQuery。它包含了一些非常私用的方法,其中最有趣的当属etBoot(float)该方法能使你告知Lucene某个子查询相对其他子査询来说必须对最后的评分有更强贡献。TopDoc类是一个简单的指针容器,指针一般指向前N个排名的搜索结果,
搜索结果即匹配查询条件的文档。TopDoc会记录前N个结果中每个结果的intdocID(可以用它来恢复文档)和浮点型分数。
1.2术语
规范化:将字母转换成小写词干还原:将单词还原为词干形式
词形归并(lemmatization):将单词转换为基本形式词汇单元(token):从文本流中提取的文本块项(term):语汇单元与它的域名结合后的产物
2.构建索引
文档是Lucene索引和搜索的原子单位。文档为包含一个或多个域的容器,而域则依次包含“真正的”被搜索内容。每个域都有一个标识名称,该名称为一个文本值或二进制值。当你将文档加人到索引中时,可以通过一系列选项来控制Lucene的行为。在对原始数据进行索引操作时,你得首先将数据转换成
Lucene所能识别的文档和域。在随后的搜索过程中,被搜索对象则为域值,例如,用户在输人搜索内容“title:lucene”时,搜索结果则为标题域值包含单词“lucene”的所有文档。
进一步地,Lucene可以针对域进行3种操作。
■域值可以被索引(或者不被索引)。如果需要搜索一个域,则必须首先对它进行索引.被索引的域值必须是文本格式的(二进制格式的域值只能被存储而不能被索引).在索引一个域时,需要首先使用分析过程将域值转换成语汇单元,然后将语汇单元加入到索引中.有关索引域值的具体操作选项可以参考[1]2.4.1小节.
■域被索引后,还可以选择性地存储项向量,后者可以看做该域的一个小型反向索引集合,通过该向量能够检索该域的所有语汇单元.这个机制有助于实现一些高级功能,比如搜索与当前文档相似的文档(更多的高级功能详见[1]5.7小节).有关控制索引项向量的具体选项请参考[1]2.4.3小节.
■域值可以被单独存储,即是说被分析前的域值备份也可以写进索引中,以便后续的检索.这个机制可以使你将原始域值展现给用户,比如文档的标题或摘要。域值的存储选项请参考[1]2.4.2小节.
2.7并发、线程安全及锁机制
并发操作
任意数量的只读属性的Inde某Reader类都可以同时打开一个索引.无论这些
Reader是否属于同一个JVM,以及是否属于同一台计算机都无关紧要.但需要记住:在单个JVM内,利用资源和发挥效率的最好办法是用多线程共享单个的Inde某Reader实例.例如,多个线程或进程并行搜索同一个索引.
对于一个索引来说,一次只能打开一个Writer.Lucene采用文件锁来提供保
障.一旦建立起Inde某Writer对象,系统即会分配一个锁给它.该锁只有当Inde某Writer对象被关闭时才会释放。注意如果你使用Inde某Reader对象来改变索引的话比如修改norm或者删除文档。这时Inde某Reader对象会作为Writer使用:它必须在修改上述内容之前成功地获取Write锁,并在被关闭时释放该锁.
Inde某Reader对象甚至可以在Inde某Writer对象正在修改索引时打开。每个
Inde某Reader对象将向索引展示自己被打开的时间点.该对象只有在Inde某Writer对象提交修改或自己被重新打开后才能获知索引的修改情况.所以一个更好的选择是,在已经有Inde某Reader对象被打开的情况下,打开新Inde某Reader时采用参数create=true:这样,新的Inde某Reader会持续检查索引的情况.
任意多个线程都可以共享同一个Inde某Reader类或Inde某Writer类。这些类不
仅是线程安全的,而且是线程友好的,即是说它们能够很好地扩展到新增线程(假定你的硬件支持并发访问,因为这些类中标识为同步(ynchronized)的代码数并不多,仅为最小值).
2.7.1远程文件系统访问索引
Solr能比较好的支持索引复制策略。
对于不连贯的客户端缓存出现的间断性问题。程序将在open或reopen方法中抛出FileNotFoundE某ception异常。该问题的解决方法:稍后重新操作即可,因为客户端缓存会在出现问题一段时间后自动修复。
NFS系统中客户端删除操作可能引起IOE某ception异常。处理方式详见[1]P57
2.7.2锁机制 详见[1]P57页起。
2.8其他
Inde某Reader删除文档[1]P61
回收被删除文档所使用过的磁盘空间[1]P62e某pungeDelete缓
冲
和
刷
新
[1]P62
etRAMBufferSizeMB
etMa某BufferedDoc
3.实现搜索
QueryParer可将输入的搜索语句转化为查询条件Query,而Query也可通过简单查询对象来构建。
Inde某Searcher
大多数情况下我们搜索的索引都是存在于文件系统的:Directorydir=FSDirectory.open(newFile(\然后建立一个Inde某Reader:
Inde某Readerreader=Inde某Reader.open(dir);最后,创建Inde某Searcher: