一 Lucene 之索引
1.1 正排索引
正排索引是指文档ID为key,表中记录每个关键词出现的次数 位置等,查找时扫描表中的每个文档中字 的信息,直到找到所有包含查询关键字的文档。 “文档1”的ID > 单词1:出现次数,出现位置列表;单词2:出现次数,出现位置列表;............。 “文档2”的ID > 此文档出现的关键词列表。 正常的索引一般是指关系型数据库里的索引。 把不同的数据存放到不同的字段中。如果要实现baidu或 google那种搜索,就需要与一条记录的多个字段进行比对,需要 全表扫描,如果数据量比较大的话, 性能就很低。 当用户在主页上搜索关键词“华为手机”时,假设只存在正向索引(forward index),那么就需要扫描索 引库中的所有文档,找出所有包含关键词“华为手机”的文档,再根据打分模型进行打分,排出名次后呈 现给用户。因为互联网上收录在搜索引擎中的文档的数目是个天文数字,这样的索引结构根本无法满足 实时返回排名结果的要求。
1.2 倒排索引
倒排索引(Inverted Index): 被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中
最常用的数据结构。通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。 “关键词1”:“文档1”的ID 出现次数 出现的位置,“文档2”的ID 出现次数 出现的位置,............。
“关键词2”:带有此关键词的文档ID列表。 倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
二 Lucene 模块构成
- Lucene 的index模块主要负责索引的创建,里面有IndexWriter。
- Lucene 的search模块主要负责对索引的搜索。
- Lucene 的QueryParser主要负责语法分析。
- Lucene 的Document相当于一个要进行索引的单元,任何可以想要被索引的文件都必须转化为Document对象才能进行索引。代表一个虚拟文档与字段,其中字段是可包含在物理文档的内容,元数据等对象。
- Lucene 的analysis 模块主要负责词法分析及语言处理而形成Term。
- Lucene 的store模块主要负责索引的读写。
三 Lucene 底层存储
Lucene的索引结构是有层次结构的,主要分以下几个层次:
索引(Index):一个目录一个索引,在Lucene中一个索引是放在一个文件夹中的。
同一文件夹中的所有的文件构成一个Lucene索引。
段(Segment):一个索引可以包含多个段,段与段之间是独立的,添加新文档可以生成新的段,不同的段可以合并。 在建立索引的时候对性能影响最大的地方就是在向索引写入文档的时候, 所以在具体应用的时候就需要对此加以控制,段(Segment) 就是实现这种控制的。 Lucene默认情况是每加入10份文档(Document)就从内存往index文件写入并生成一个段然后每10个段(Segment)就合并成一个段(Segment). 这些控制的变量如下:
IndexWriter属性 默认值 描述
MergeFactory 10 控制segment合并的频率和大小
MaxMergeDocs Int32.MaxValue 限制每个segment中包含的文档数
MinMergeDocs 10 当内存中的文档达到多少的时候再写入segment
文档(Document): 文档是我们建索引的基本单位,不同的文档是保存在不同的段中的,一个段可以包含多篇文档。 新添加的文档是单独保存在一个新生成的段中,随着段的合并,不同的文档合并到同一个段中。
域(Field): 一篇文档包含不同类型的信息,可以分开索引,比如标题,内存,作者等,都可以保存在不同的域里。不同域的索引方式可以不同。
词(Term):词是索引的最小单位,是经过词法分析和语言处理后的字符串。
Lucene的索引结构中,即保存了正向信息,也保存了反向信息。 所谓正向信息:
按层次保存了从索引一直到词的包含关系:索引(Index) –> 段(segment) –> 文档(Document) –> 域(Field) –> 词(Term)
也即此索引包含了那些段,每个段包含了那些文档,每个文档包含了那些域,每个域包含了那些词。
既然是层次结构,则每个层次都保存了本层次的信息以及下一层次的元信息,也即属性信息,比如一本介绍中国地理的书,应该首先介绍中国地理的概况,以及中国包含多少个省,每个省介绍本省的基本概况.及包含多少个市,每个市介绍本市的基本概况及包含多少个县,每个县具体介绍每个县的具体情况。
所谓反向信息:
保存了词典到倒排表的映射:词(Term) –> 文档(Document)
三 Lucene 索引创建和搜索流程
第一步:一些要索引的原文档(Document)数据
比如我们需要分析的数据内容是:
采集数据分类: 1、对于互联网上网页,可以使用工具将网页抓取到本地生成html文件。 2、数据库中的数据,可以直接连接数据库读取表中的数据。 3、文件系统中的某个文件,可以通过I/O操作读取文件的内容。
Lucene Core is a Java library providing powerful indexing and search
features, as well as spellchecking, hit highlighting and advanced
analysis/tokenization capabilities. The PyLucene sub project provides
Python bindings for Lucene Core.
Solr is highly scalable, providing fully fault tolerant distributed
indexing, search and analytics. It exposes Lucene's features through easy
to use JSON/HTTP interfaces or native clients for Java and other languages.
The Apache Hadoop software library is a framework that allows for the
distributed processing of large data sets across clusters of computers
using simple programming models.
第二步 创建文档对象 进行词法分析 语言处理 将原文档传给分词器(Tokenizer) 形成一系列词(Term) 获取原始内容的目的是为了索引,在索引前需要将原始内容创建成文档(Document),文档中包括一
个一个的域(Field),域中存储内容。每个Document可以有多个Field。 每个文档都有一个唯一的编号,就是文档id
当然这里传给分词器的操作在addDocument后会自行调用 ,将原始内容创建为包含域(Field)的文档 (document),需要再对域中的内容进行分析,分析成为一个一个的单词(Term)。
第三步: 索引创建 将得到的词(Term)传给索引组件(Indexer) 形成倒排索引结构 对所有文档分析得出的词汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单
元从而找到Document(文档)。 创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构。 倒排索引结构是根据内容(词汇)找文档,如下图:
第四步: 通过索引存储器 将索引写入到磁盘
一次查询的经过:
a) 用户输入查询语句
b) 对查询语句经过词法分析和语言分析得到一系列词(Term)
c) 通过语法分析得到一个查询树
d) 通过索引存储将索引读到内存
e) 利用查询树搜索索引,从而得到每个词(Term)的文档列表,对文档列表进行交、差、并得到结果文 档
f) 将搜索到的结果文档按照对查询语句的相关性进行排序
g) 返回查询结果给用户
本文由 chaoohuua 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2025/05/09 01:32