Lucene概览

1. 背景

1.1 Lucene是什么

       Luene是一款高性能、可扩展的信息检索库,用于完成文档元信息、文档内容等搜索功能。用户可以使用Lucene 或 基于Lucene的成熟产品Nutch/Solr/Elasticsearch等来快速构建搜索服务,如文件搜索、网页搜索等。

1.2 需求

       随着信息量的爆炸式增长,人们开始发明各种各样的方案来对信息进行管理,加快信息获取速度。传统方案如新华字典中的汉语拼音音节索引及部首检字表索引、图书馆使用的杜威十进制分类法( 330.94 表欧洲经济学=330 表经济学+ .9 表地区别论述 + .04 表欧洲)等,互联网时代的方案如Windows资源管理器中的搜索功能、Google、百度等。Lucene也是互联网时代的一种方案,可用于满足大量信息检索场景:

  • 文件搜索:类似GitHub的代码搜索;
  • 网页搜索:各门户网站的站内网页搜索;
  • App搜索:类似App Store支持的应用搜索;
  • 商品搜索:美团内的美食商品搜索。

       但与Windows资源管理器、Google、百度等不同的是,Lucene并不是一个开箱即用型的服务。它面向程序开发者,是一个Java开发的、大小仅2MB左右的类库,专注于信息检索技术的文本索引和搜索功能等通用性部分,而把信息采集处理、用户交互UI、商业逻辑等业务相关性部分交给应用层。

1.3 相关产品

       尽管在Java世界lucene已经是标准的全文检索程序,但是C/C++世界并没有相应的工具。虽然Lucene被广泛移植到其他语言中(C/C++、C#、Python、PHP、Perl等),但其他语言版本的活跃程度一般。Xapian填补了这个缺憾,它的API和检索原理和lucene在很多方面都很相似。

       Lucene另一方面,Lucene仅仅是一个Java类库,对于线上大规模使用,除了需要经过封装开发形成产品外,还需要考虑可靠性、分布式化等问题。因此出现了基于Lucene的产品化系统,例如Nutch、Solr、Elasticsearch等。

1.4 作者

       Lucene的作者Doug Cutting,同时也是Nutch、Hadoop的创始人。

2. 初步使用

       下面通过构造一个简单的文本文件搜索程序,来介绍Lucene的写入(索引流程)、读取(搜索流程)等基本使用。

2.1 索引流程

  • 程序入口:读取dataDir目录下的文件,写入目标目录:
  • 其中,Indexer类构造函数的核心为定义一个Lucene的IndexWriter对象:
  • indexer.index()用于遍历目录下的所有文件,对其中的文本文件建立索引:
  • 其中indexFile为建立索引的核心实现,具体如下:

2.2 搜索流程

  • 程序入口:获取搜索请求
  • 其中,search为搜索文件的核心实现,具体如下:

       到这里,我们仅通过一两百行代码即完成了一个最简单的文本文件搜索功能。

3. 基本原理

       正如前面的文本文件搜索程序所示,Lucene的信息检索功能主要包含两个主要流程:索引 和 搜索。这两部分的整体流程如下:

  • 索引流程
    • 对待索引的文档进行分词处理:(1)
    • 结合分词处理的结果,建立词典表 和 倒排索引:(2)
    • 将倒排索引写入索引存储:(3)、(4)
  • 搜索流程
    • 对用户的查询语句进行词法、语法分析:(a)、(b)
    • 搜索索引得到结果文档集,其中涉及到从索引存储中加载索引到内存的过程:(c)、(d)、(e)
    • 对搜索结果进行排序并返回结果(f)、(g)

       下面我们结合图例,对上述索引、搜索流程进行具体介绍。

3.1 索引流程

3.1.1 分词处理

  • 将待索引的文档传递给分词器进行处理,我们样例程序中的StandardAnalyzer即为标准英文分词器,如果需要中文分词,可以使用开源界贡献的插件或自定义。
  • 分词过程会把文档拆分成一个个独立的词(Term),期间会去除标点符号和停用词(“the”、“this”、“a”...),并对词做小写化等处理。分词后的结果样例如下:

3.1.2 建立词典表 和 倒排索引

  • 对分词的结果进行排序,建立词典列表:
  • 合并相同的词,建立词典表 和 倒排表

3.1.3 存储索引

  • Lucene为了加快索引速度,采用了LSM Tree结构,先把索引数据缓存在内存。
  • 当内存空间占用较高 或 达到时间限制后,内存中的数据会被写入磁盘形成一个数据段(segment),segment实际包含词典、倒排表、字段数据等等多个文件。

3.2 搜索流程

3.2.1 词法、语法分析

  • 对用户的请求语句进行词法、语法分析,生成查询语法树,把文本请求转换为Lucene理解的请求对象。例如对查询“lucene AND Solr”的分析后生成的语法树如下:

3.2.2 搜索索引

  • 按照查询语法树,搜索索引获取最终匹配的文档id集合:

3.2.3 相关性排序

  • 对查询结果进行打分排序,获取Top N的文档id集合,获取文档原始数据后返回用户。影响打分的因数因素包含:
    • 词频/文档频率(TF/IDF):词频越高打分越高,文档频率越高打分越低
    • boost:lucene支持针对不同字段设置权重,例如当Term出现在标题字段时的打分,通常高于其出现在文档内容中的打分。
    • ……

       至此,我们对Lucene的索引、查询流程有了一个直观的认识。

4. 核心存储

       在3.1.3小节介绍存储索引部分时我们提到,Lucene内存中的数据最终被分为多个文件写入磁盘进行存储。这里我们先整体介绍下Lucene底层的核心存储文件,后续会结合读写流程逐一详细介绍。每个Lucene Index的核心存储文件如下图:

       之前我们提到的词典表、倒排表、字段数据分别存储在上图中的segment1.tim、segment1.doc、segment1.fdt文件中。其他文件存储的数据内容可以参考下表:

文件

后缀

描述

索引信息

segments_n

commit point,存储当前生效的segment集合

写锁

write.lock

避免多个写类IndexWriter同时操作同一个Index

词典表

tim

存储对应segment内包含的term、文档频率,按字典序排序

词典表索引

tip

每n条词典表记录抽取一条建立的稀疏索引,用于加快词典表的查找

倒排表

doc

存储每个term对应的文档id列表及其词频信息

位置数据

pos

存储term在文档中出现的位置、偏移等信息

PointFormat

dim

Lucene 6.0引入的、针对数值类型的新索引,通过block KD-tree structure实现,加快范围查询

PointFormat索引

dii

加快PointFormat索引查找

字段信息

fnm

存储segment包含的字段名、字段类型、索引属性等信息

字段行存

fdt

以行存方式存储字段数据,通过文档id可以在fdt中获取对应文档的字段数据

字段行存索引

fdx

针对字段行存数据建立的稀疏索引,加快字段数据的定位

字段列存

dvd

Lucene 4.0引入,以列存方式存储字段数据,用于加快排序、聚合等操作

列存元数据

dvm

dvd文件的元数据

段信息

si

记录segment大小、版本、文件列表等元信息

       另外,列举一个Lucene核心存储文件的实际样例,方便参考上面描述对照理解:

5.小结

       本文主要从整体角度介绍Lucene,通过样例程序、基本原理简介等方式建立对Lucene的直观理解。但对Lucene底层存储、主要流程实现等没有详细深入的介绍,后续我们会通过具体文章详细介绍,欢迎大家一起交流讨论。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据和云

深入剖析:关于cache buffers chains的经典案例处理详解

? 卢文星 目前就职云和恩墨,南区交付工程师,有超过8年超大型数据库管理经验,擅长Oracle数据库性能优化与升级迁移。 作者介绍 故障现象 某省税务核心业务...

2796
来自专栏数据和云

深入解析:DB2 V10.5新特性列式存储表的优点与缺点

李培杨 云和恩墨西区交付技术顾问,有多年数据库运维经验,长期服务移动运营商行业客户,熟悉 DB2 数据库故障诊断,数据库迁移升级。

1304
来自专栏Java架构沉思录

MySQL 性能优化,优化设计及设计原则解读

1. 关系明确(理清表之间的关系,可以通过冗余的方式提高效率) 2. 节省空间(根据业务经验,设置字段长短) 3. 提高效率

772
来自专栏腾讯云Elasticsearch Service

Elasitcsearch 底层系列 Lucene 内核解析之Lucene概览

       Luene是一款高性能、可扩展的信息检索库,用于完成文档元信息、文档内容等搜索功能。用户可以使用Lucene 或 基于Lucene的成熟产品Nut...

2321
来自专栏Hadoop数据仓库

HAWQ技术解析(十二) —— 查询优化

        即便对SELECT等数据库查询语句已经很熟悉了,但HAWQ里的查询有其自己的特点,还是需要研究一下。 一、HAWQ的查询处理流程        ...

6286
来自专栏数据和云

超实用运维经验:TEMP表空间不足、热块竞争经典案例

作者介绍 ? 邓秋爽 云和恩墨技术专家,擅长于SQL tuning、troubleshooting 系统运行过程中可能遇见各种各样的性能问题,如果仅仅是当前系统...

3175
来自专栏数据和云

SQL查询提速秘诀,避免锁死数据库的数据库代码

由于数据库领域仍相对不成熟,每个平台上的 SQL 开发人员都在苦苦挣扎,一次又一次犯同样的错误。当然,数据库厂商在取得一些进展,并继续在竭力处理较重大的问题。

1643
来自专栏JavaWeb

原 荐 MySQL-性能优化-优化设计和设计

1934
来自专栏Elasticsearch实验室

Elasitcsearch 底层系列 Lucene 内核解析之Lucene概览

       Luene是一款高性能、可扩展的信息检索库,用于完成文档元信息、文档内容等搜索功能。用户可以使用Lucene 或 基于Lucene的成熟产品Nut...

2548
来自专栏更流畅、简洁的软件开发方式

细分主键

  主键本身是很简单的,但是围绕他产生的故事就不是那么简单了。 1、 管理 这个是最重要的,没有规矩不成方圆,主键要如何管理一定要实现确定好了,甚至有必要为此写...

2026

扫码关注云+社区

领取腾讯云代金券