概述

Lucene 作为 Apache 开源的一款搜索工具,一直以来是实现搜索功能的神兵利器,现今火热的 Solr 和 Elasticsearch 均基于该工具包进行开发,而 Lucene 之所以能在搜索中发挥至关重要的作用正是因为倒排索引。因此,本文将介绍一下倒排索引的概念以及倒排索引在 Lucene 中的实现。

基本原理

什么是倒排索引

搜索的核心需求是全文检索,全文检索简单来说就是要在大量文档中找到包含某个单词出现的位置,在传统关系型数据库中,数据检索只能通过 like 来实现。

例如需要在酒店数据中查询名称包含公寓的酒店,需要通过如下 sql 实现:

select * from hotel_table where hotel_name like '%公寓%';

这种实现方式实际会存在很多问题:

  • 无法使用数据库索引,需要全表扫描,性能差
  • 搜索效果差,只能首尾位模糊匹配,无法实现复杂的搜索需求
  • 无法得到文档与搜索条件的相关性

搜索的核心目标实际上是保证搜索的效果和性能,为了高效的实现全文检索,我们可以通过倒排索引来解决。

倒排索引是区别于正排索引的概念:

  • 正排索引:是以文档对象的唯一 ID 作为索引,以文档内容作为记录。
  • 倒排索引:Inverted index,指的是将文档内容中的单词作为索引,将包含该词的文档 ID 作为记录。

倒排索引的生成过程

下面通过一个例子来说明下倒排索引的生成过程。

假设目前有以下两个文档内容:

苏州街维亚大厦 
桔子酒店苏州街店

其处理步骤如下:

1、正排索引给每个文档进行编号,作为其唯一的标识。

文档 id content
1 苏州街维亚大厦
2 桔子酒店苏州街店

2、生成倒排索引:

  • 首先要对字段的内容进行分词,分词就是将一段连续的文本按照语义拆分为多个单词,这里两个文档包含的关键词有:苏州街、维亚大厦…
  • 然后按照单词来作为索引,对应的文档 id 建立一个链表,就能构成上述的倒排索引结构。
Word 文档 id
苏州街 1,2
维亚大厦 1
维亚 1
桔子 2
酒店 2
大赛 1

有了倒排索引,能快速、灵活地实现各类搜索需求。整个搜索过程中我们不需要做任何文本的模糊匹配。

例如,如果需要在上述两个文档中查询 苏州街桔子 ,可以通过分词后 苏州街 查到 1、2,通过 桔子 查到 2,然后再进行取交取并等操作得到最终结果。

倒排索引的结构

根据倒排索引的概念,我们可以用一个 Map来简单描述这个结构。这个 Map 的 Key 的即是分词后的单词,这里的单词称为 Term,这一系列的 Term 组成了倒排索引的第一个部分 —— Term Dictionary (索引表,可简称为 Dictionary)。

倒排索引的另一部分为 Postings List(记录表),也对应上述 Map 结构的 Value 部分集合。

记录表由所有的 Term 对应的数据(Postings) 组成,它不仅仅为文档 id 信息,可能包含以下信息:

  • 文档 id(DocId, Document Id),包含单词的所有文档唯一 id,用于去正排索引中查询原始数据。
  • 词频(TF,Term Frequency),记录 Term 在每篇文档中出现的次数,用于后续相关性算分。
  • 位置(Position),记录 Term 在每篇文档中的分词位置(多个),用于做词语搜索(Phrase Query)。
  • 偏移(Offset),记录 Term 在每篇文档的开始和结束位置,用于高亮显示等。

Lucene 倒排索引实现

全文搜索引擎在海量数据的情况下是需要存储大量的文本,所以面临以下问题:

  • Dictionary 是比较大的(比如我们搜索中的一个字段可能有上千万个 Term)
  • Postings 可能会占据大量的存储空间(一个Term多的有几百万个doc)

因此上面说的基于 Map 的实现方式几乎是不可行的。

在海量数据背景下,倒排索引的实现直接关系到存储成本以及搜索性能。

为此,Lucene 引入了多种巧妙的数据结构和算法。其倒排索引实现拥有以下特性:

  • 以较低的存储成本存储在磁盘 (索引大小大约为被索引文本的20-30%)
  • 快速读写

下面将根据倒排索引的结构,按 Posting List 和 Terms Dictionary 两部分来分析 Lucene 中的实现。

Posting List 实现

PostingList 包含文档 id、词频、位置等多个信息,这些数据之间本身是相对独立的,因此 Lucene 将 Postings List 被拆成三个文件存储:

  • doc后缀文件:记录 Postings 的 docId 信息和 Term 的词频
  • pay后缀文件:记录 Payload 信息和偏移量信息
  • pos后缀文件:记录位置信息

基本所有的查询都会用 .doc 文件获取文档 id,且一般的查询仅需要用到 .doc 文件就足够了,只有对于近似查询等位置相关的查询则需要用位置相关数据。

三个文件整体实现差不太多,这里以.doc 文件为例分析其实现。

.doc 文件存储的是每个 Term 对应的文档 Id 和词频。每个 Term 都包含一对 TermFreqs 和 SkipData 结构。

其中 TermFreqs 存放 docId 和词频信息,SkipData 为跳表信息,用于实现 TermFreqs 内部的快速跳转。

Term Dictionary 实现

Terms Dictionary(索引表)存储所有的 Term 数据,同时它也是 Term 与 Postings 的关系纽带,存储了每个 Term 和其对应的 Postings 文件位置指针。

其他更多介绍请参考:ES之倒排索引详解_wh柒八九的博客-CSDN博客_es倒排索引

ElasticSearch倒排索引详解相关推荐

  1. ElasticSearch搜索引擎详解-持续更新中

    ElasticSearch搜索引擎详解 1. ElasticSearch概述 1.1 elasticsearch是什么 1.2 全文搜索引擎 1.3 elasticsearch and solr 1. ...

  2. elasticsearch配置文件详解

    配置文件详解 配置文件位于es根目录的config目录下面,有elasticsearch.yml和logging.yml两个配置,主配置文件是elasticsearch.yml,日志配置文件是logg ...

  3. Elasticsearch Pipeline 详解

    文章目录 Ingest Node 简介 Ingest Node 简介 Pipeline.Processors Pipeline 定义 简介 Simulate Pipeline API 访问 Pipel ...

  4. ElasticSearch配置详解

    2019独角兽企业重金招聘Python工程师标准>>> 配置文件详解 配置文件位于es根目录的config目录下面,有elasticsearch.yml和logging.yml两个配 ...

  5. ElasticSearch Client详解

    从本文开始,将与大家进入到Elasticsearch的精妙世界中来,基于当前最新的6.4.x版本. 本文将重点探讨ElasticSearch Client的相关知识,重点关注TransportClie ...

  6. ElasticSearch(ES)详解(二)

    ElasticSearch(ES)详解(二) 前言 一.ES集群讲解 (一)基本词条介绍 (二)集群架构原理 1.写入原理 2.检索原理 二.集群部署及管理 (一)部署集群 (二)管理集群 前言 上一 ...

  7. elasticsearch入门详解以及mapping介绍

    本文目录 elasticsearch简介 elasticsearch的Type区别 核心数据类型: 复杂数据类型 倒排索引 index内部模型 自动识别规则 匹配查询 elasticsearch 中t ...

  8. ElasticSearch使用详解

    一.搜索引擎介绍 在互联网项目中,涉及到检索的业务需求很多,我们可以通过对数据库的模糊查询实现检索功能,但是针对大数据量的操作,基于数据库的检索就显得力不从心了(查询效率很低).所需我们要寻求一种高效 ...

  9. elasticsearch-jdbc实现MySQL同步到ElasticSearch深入详解

    1.如何实现mysql与elasticsearch的数据同步? 逐条转换为json显然不合适,需要借助第三方工具或者自己实现.核心功能点:同步增.删.改.查同步. 2.mysql与elasticsea ...

最新文章

  1. Hystrix 超时配置重写
  2. 使用Python进行端口扫描
  3. 四大运营商的5G部署路线一览
  4. 软件测试的测什么,软件测试人员应具备哪些能力?
  5. WebService(基于AXIS的WebService编程)
  6. 如何使用cout以全精度打印双精度值?
  7. html 文字倒映效果,HTML图片CSS滤镜—倒影效果
  8. 利用 MongoDB 和 Solr 实现全文搜索
  9. python怎么将输入的数字变成列表_Python键盘输入转换为列表的实例
  10. Java中sleep,wait,yield,join的区别
  11. 华为将升级鸿蒙,华为将弃用安卓?Mate40将成为首款可升级鸿蒙OS的手机
  12. 高并发异步uwsgi+web.py+gevent
  13. [SCM]源码管理 - SVN:externals
  14. matlab剪切板中内容清除,如何清空剪贴板内容?剪切板内容清理过程
  15. VLAN tagged和untagged
  16. mysql 两阶段加锁_MySql-两阶段加锁协议
  17. ****彩印管理系统部署及开发心得
  18. Android动画的使用——补间动画
  19. Java统一日志处理
  20. 计算机毕业设计Java-ssmC语言教学辅导网站源码+系统+数据库+lw文档

热门文章

  1. A Game of Thrones(57)
  2. Docker的Jenkins Pipeline工作流
  3. python elif格式_python中elif 结构语句怎么判断?
  4. 常用的图像特征有颜色特征、纹理特征、形状特征、空间关系特征。
  5. 0基础可以学习大数据吗?
  6. CANoe-什么是Vector Tool Platform(全网唯一讲明白的文章)
  7. window下phpstudy用nginx报错No input file specified. nginx日志The filename, directory name, or volum label
  8. 快速傅里叶变换python_快速傅里叶变换及python代码实现
  9. 诺基亚7 android 9,诺基亚7 Plus喜迎Android 9更新:带来众多更新
  10. vr应急救援模拟系统是什么何优势|广州华锐互动