共计 2606 个字符,预计需要花费 7 分钟才能阅读完成。
Lucene 是一款高性能的、可扩展的信息检索(IR)工具库。信息检索是指文档搜索、文档内信息搜索或者文档相关的元数据搜索等操作。
索引过程
获取内容
建立文档
获取原始内容后,就需要对这些内容进行索引,必须首先将这些内容转换成部件(通常称为文档),以供搜索引擎使用。文档主要包括几个带值的域,比如标题、正文、摘要、作者和链接。
文档分析
搜索引擎不能直接对文本进行索引:确切地说,必须将文本分割成一系列被称为语汇单元的独立的原子元素。每一个语汇单元大致与语言中的“单词”对应起来。
文档索引
在索引步骤中,文档被加入到索引列表。
搜索组件
搜索处理过程就是从索引中查找单词,从而找到包含该单词的文档。搜索质量主要由查准率和查全率来衡量。查全率用来衡量搜索系统查找相关文档的能力;而查准率用来衡量搜索系统过滤非相关文档的能力。
索引过程的核心类
IndexWriter Directory
Analyzer
Document
Field
IndexWriter
索引过程的核心组件。这个类负责创建新索引或者打开已有索引,以及向索引中添加、删除或更新被索引文档的信息。可以把 IndexWriter 看作这样一个对象:它为你提供针对索引文件的写入操作,但不能用于读取或搜索索引。IndexWriter 需要开辟一定空间来存储索引,该功能可以由 Directory 完成。
Directory
该类描述了 Lucene 索引的存放位置。它是一个抽象类,它的子类负责具体指定索引的存储路径。用 FSDirectory.open 方法来获取真实文件在文件系统的存储路径,然后将它们一次传递给 IndexWriter 类构造方法。IndexWriter 不能直接索引文本,这需要先由 Analyzer 将文本分割成独立的单词才行。
Analyzer
文本文件在被索引之前,需要经过 Analyzer(分析器)处理。Analyzer 是由 IndexWriter 的构造方法来指定的,它负责从被索引文本文件中提取语汇单元,并提出剩下的无用信息。如果被索引内容不是纯文本文件,那就需要先将其转换为文本文档。对于要将 Lucene 集成到应用程序的开发人员来说,选择什么样 Analyzer 是程序设计中非常关键的一步。分析器的分析对象为文档,该文档包含一些分离的能被索引的域。
Document
Document 对象代表一些域(Field)的集合。文档的域代表文档或者文档相关的一些元数据。元数据(如作者、标题、主题和修改日期等)都作为文档的不同域单独存储并被索引。Document 对象的结构比较简单,为一个包含多个 Filed 对象容器;Field 是指包含能被索引的文本内容的类。
Field
索引中的每个文档都包含一个或多个不同命名的域,这些域包含在 Field 类中。每个域都有一个域名和对应的域值,以及一组选项来精确控制 Lucene 索引操作各个域值。
搜索过程中的核心类
IndexSearcher
Term
Query
TermQuery
TopDocs
IndexSearcher
该类用于搜索由 IndexWriter 类创建的索引,它是连接索引的中心环节。可以将 IndexSearcher 类看作是一个以只读方式打开索引的类。它需要利用 Directory 实例来掌控前期创建的索引,然后才能提供大量的搜索方法。
Term
Term 对象是搜索功能的基本单元。Term 对象包含一对字符串元素:域名和单词(或域名文本值)。
Query
包含了一些非常有用的方法,TermQuery 是它的一个子类。
TermQuery
该类提供最基本的查询,用来匹配指定域中包含特定项的文档。
TopDocs
该类是一个简单的指针容器,指针一般指向前 N 个排名的搜索结果,搜索结果即匹配查询条件的文档。
Lucene 如何对搜索内容进行建模
文档和域
文档是 Lucene 索引和搜索的原子单位。文档为包含一个或多个域的容器,而域则依次包含“真正的”被搜索内容。每个域都有一个标识名称,该名称为一个文本值或二进制值。如:用户在输入搜索内容“title:lucene”时,搜索结果则为标题域值包含单词“lucene”的所有文档。
Lucene 可以针对域进行 3 种操作:
域值可以被索引。如果需要搜索一个域,则必须首先对它进行索引。被索引的域值必须是文本格式的(二进制格式的域值只能被存储而不能被索引)。在索引一个域时,需要首先使用分析过程将域值转换为语汇单元,然后将语汇单元加入到索引中。
域被索引后,还可以选择性地存储项向量,后者可以看作该域的一个小型反向索引集合,通过该向量能够检索该域的所有语汇单元。这个机制有助于实现一些高级功能,比如搜索与当前文档相似的文档。
域值可以被单独存储,即是说被分析前的域值备份也可以写进索引中,以便后续的检索。这个机制可以使你将原始值展现给用户,比如文档的标题或摘要。
灵活的架构 与数据库不同的是,Lucene 没有一个确定的全局模式;Lucene 要求在进行索引操作时简单化或反向规格化原始数据。
理解索引过程
在索引操作期间,文本首先从原始数据中提取出来,并用于创建对应的 Document 实例,该实例包含多个 Field 实例,它们都用来保存原始数据信息。随后的分析过程将域文本处理成大量语汇单元。最后将语汇单元加入到段结构中。
提取文本和创建文档
使用 Lucene 索引数据时,必须先从数据中提取纯文本格式信息,以便 Lucene 识别该文本并建立对应的 Lucene 文档。
分析文档
一旦建立其 Lucene 文档和域,就可以调用 IndexWriter 对象的 addDocument 方法将数据传递给 Lucene 进行索引操作了。在索引操作时,Lucene 首先分析文本,将文本数据分割成语汇单元串,然后对它们执行一些可选操作。
向索引添加文档
对输入数据分析完毕后,就可以将分析结果写入索引文件中。Lucene 将输入数据以一种倒排索引的数据结构进行存储。在进行关键字快速查找时,这种数据结构能够有效利用磁盘空间。Lucene 使用倒排数据结构的原因是:把文档中提取出的语汇单元作为查询关键字,而不是将文档作为中心实体,这种思想很像书籍的索引与页码的对应关系。
索引段
Lucene 索引都包含一个或多个段。每个段都是一个独立的索引,它包含整个文档索引的一个子集。每当 writer 刷新缓冲区增加的文档,以及挂起目录删除操作时,索引文件都会建立一个新段。在搜索索引时,每个段都是单独访问的,但搜索结果是合并后返回的。