首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

lucene运用教程2 -索引技术

2012-09-07 
lucene使用教程2 --索引技术索引库结构—倒排序索引我们需要对文档进行预处理,建立一种便于检索的数据结构,

lucene使用教程2 --索引技术
索引库结构—倒排序索引

    我们需要对文档进行预处理,建立一种便于检索的数据结构,以此来提高信息检索的速度,这种数据结构就是索引。目前广泛使用的一种索引方式是倒排序索引。(说明:以下只是用于说明倒排序索引的结构,最终的索引结构要复杂的多(要考虑更多、更复杂的情况)。例如还要存储关键词在文本中的编号位置,或是首字母的字符位置等信息。)

    倒排序索引的原理就如同查字典。要先查目录,得到数据对应的页码,在直接翻到指定的页码。不是在文章中找词,而是从目录中找词所在的文章。这需要在索引库中生成一个词汇表(目录),在词汇表中的每一个条记录都是类似于“词à所在文档的编号列表”的结构,记录了每一个出现过的单词,和单词出现的地方(哪些文档)。查询时先查词汇表,得到文档的编号,再直接取出相应的文档。


    把数据转成指定格式放到索引库中的操作叫做建立索引。建立索引时,在把数据存到索引库后,再更新词汇表。进行搜索时,先从检索词汇表开始,然后找到相对应的文档。如果查询中仅包含一个关键词,则在词汇表中找到该单词,并取出他对应的文档就可以了。如果查询中包含多个关键词,则需要将各个单词检索出的记录进行合并再取出相应的文档记录。

    如果词汇表中有一个词“传智播客”对应的文档编号列表为“1”。现在又有添加了一个包含“传智播客”的文档,则词汇表中的“传智播客”词后对应的编号列表变成了“1,2”。因为关键词的数量受实际语言的限制,所以不用担心词汇表会变的很大。

索引文件的检索与维护,更新是先删除后创建

维护倒排索引有三个操作:添加、删除和更新文档。但是更新操作需要较高的代价。因为文档修改后(即使是很小的修改),就可能会造成文档中的很多的关键词的位置都发生了变化,这就需要频繁的读取和修改记录,这种代价是相当高的。因此,一般不进行真正的更新操作,而是使用“先删除,再创建”的方式代替更新操作


建立索引的执行过程(Store、Index)

在建立索引时,先要把文档存到索引库中,还要更新词汇表

我们做的操作:

    1、把数据对象转成相应的Document,其中的属性转为Field。

    2、调用工具IndexWriter的addDocument(doc),把Document添加到索引库中。

Lucene做的操作:

    1、把文档存到索引库中,并自动指定一个内部编号,用来唯一标识这条数据。内部编号类似于这条数据的地址,在索引库内部的数据进行调整后,这个编号就可能会改变,同时词汇表中引用的编号也会做相应改变,以保证正确。但我们如果在外面引用了这个编号,前后两次去取,得到的可能不是同一个文档!所以内部编号最好只在内部用。

    2、更新词汇表。把文本中的词找出并放到词汇表中,建立与文档的对应关系。要把哪些词放到词汇表中呢,也就是文本中包含哪些词呢?这就用到了一个叫做Analyzer(分词器)的工具。他的作用是把一段文本中的词按规则取出所包含的所有词。对应的是Analyzer类,这是一个抽象类,切分词的具体规则是由子类实现的,所以对于不同的语言(规则),要用不同的分词器

在把对象的属性转为Field时,相关代码为:doc.add(newField("title", article.getTitle(),Store.YES, Index.ANALYZED))。

    第三与第四个参数的意思为:

枚举类型

枚举常量

说明

Store

NO

不存储属性的值

YES

存储属性的值

Index

NO

不建立索引

ANALYZED

分词后建立索引

NOT_ANALYZED

不分词,把整个内容作为一个词建立索引

说明:Store是影响搜索出的结果中是否有指定属性的原始内容。Index是影响是否可以从这个属性中查询(No),或是查询时可以查其中的某些词(ANALYZED),还是要把整个内容作为一个词进行查询(NOT_ANALYZED)。

从索引库中搜索的执行过程(QueryParser、TopDocs、ScoreDoc)

1、把要查询字符串转为Query对象。这就像在Hibernate中使用HQL查询时,也要先调用Session.createQuery(hql)转成Hibernate的Query对象一样。把查询字符串转换成Query是使用QueryParser,或使用MultiFieldQueryParser。查询字符串也要先经过Analyzer(分词器)。要求搜索时使用的Analyzer要与建立索引时使用的Analzyer要一致,否则可能搜不出正确的结果。

2、用IndexSearcher.search(),进行查询,得到结果。此方法返回值为TopDocs,是包含结果的多个信息的一个对象。其中有totalHits 代表决记录数,ScoreDoc的数组。ScoreDoc是代表一个结果的相关度得分与文档编号等信息的对象。

3、取出要用到的数据列表。调用IndexSearcher.doc(scoreDoc.doc)以取出指定编号对应的Document数据。




热点排行