elasticsearch的倒排索引及算法简介

本文介绍了倒排索引的基本概念,包括倒排表、词项字典和词项索引,并详细探讨了两种主要的postinglist压缩算法:FOR算法和RBM算法。FOR算法通过斐波那契数列实现数据压缩;RBM算法则采用32位二进制数进行数据拆分,并介绍了三种不同的数据结构容器(ArrayContainer, BitmapContainer, RunContainer)及其适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录:

1、什么是倒排索引

2、posting list的两种压缩算法:

      FOR(Frame of Reference)算法

      RBM(Roaring Bitmaps)算法

              RBM的三种存储:ArraysContainer/BitmapContainer/RunContainer

 

 

正文:

一、什么是倒排索引?

倒排索引包含三个内容:

      1、倒排表(posting list)             存储搜索数据的id列表

      2、词项字典(term dictionary)   存储数据仓库中的词汇

      3、词项索引(term index)          标识当前词项是不是被搜索

看图:

 

二、posting list的存储算法

1)FOR压缩算法

    利用斐波那契数列(前两项的和等于第三项)算法,将原始数据压缩为有顺序的一个或多个斐波那契数列。这一个或多个菲波那切数列数列就称之为delta list。

如图:

 

 

这种算法比较适合原始数据都比较小的数字,对于有大的数字来讲,压缩效果不是太好。

 

2)RBM压缩算法

    这种算法会把一个数转换为32位的二进制数之后,然后拆分为高16位和低16位存储。也就是将原数除以65536(即2^16),商是高位,余数是低位。然后高位相同的,会将余数存储到同一个队列中。

示例图:

 

RBM算法有点类似hashmap里面链表hash算法。

对于余数的队列存储又分为不同的数据结构容器(Container)。

Container有三种:

a) ArrayContainer

因为余数一定是在1~65536之间的,所以这种方式就是给每个数字划定固定的16bit的磁盘空间。因此这种存储会随着文件的增多,呈线性增长。当有4096个数的时候,这个存储空间就达到了65536bit,即8KB。

示例图:

b) BitmapContainer

这个存储会利用一串二进制数来标识多个数字,二进制数为1的索引位置就是所表示的数字。用65536个二进制数字就可以表示0~65536之间所有的数。也就是对于这种存储来讲,是固定的65536bit空间,即8KB.

示例图:

 

对于ArrayContainer和BitmapContainer,有一个图来表示数据量文件数多少与空间占用关系:

从关系中可以看出,如果一组文件数少于4096,使用ArrayContainer更省空间。如果文件数大于4096,使用BitmapContainer更省空间。

c)RunContainer

   这种存储只适合处理连续的数字。对于连续的数字,只存储开头和结尾的数字即可,空间大小就是用2个int型数字来存储,共需要8Byte。 现实中这种情况比较少见。

 

 

 

 

 

### Elasticsearch 倒排索引的工作原理及实现方式 #### 什么是倒排索引倒排索引是一种用于快速全文检索的数据结构。其基本思想是通过构建一个从关键词到文档列表的映射关系,使得查询某个词时可以迅速找到包含该词的所有文档[^1]。 #### 倒排索引的核心组成部分 倒排索引主要由两部分组成: 1. **Term Dictionary(词条字典)**:存储所有的唯一词条及其元信息,比如频率统计等。这些词条按照字母顺序排列以便于高效查找。 2. **Postings List(倒排列表)**:记录哪些文档包含了特定词条以及词条在这些文档中的位置和其他相关信息。 例如,在给定的例子中,“Elasticsearch”,“is”,“a”等等都是词条,而它们对应的文档编号则构成了各自的倒排列表[^2]。 #### 构建过程概述 当向 Elasticsearch 中新增加一条记录或者更新已有数据的时候,系统会执行如下几个步骤来创建或维护倒排索引: 1. 对输入文本进行分析处理(Analysis),这通常涉及分词(Tokenization),去除停用词(Stop Words Removal)以及其他预处理操作; 2. 将经过处理后的各个单词加入 Term Dictionary 并相应扩展 Postings Lists;如果单词已经存在于 Term Dictionary,则只需在其关联的 Posting List 上增加新的条目即可; 3. 定期优化物理存储形式以提高访问效率并节省空间——这一阶段可能涉及到合并多个小型段(segment)成更大的段文件,并重新写入硬盘。 为了加速搜索速度,还引入了一些辅助性的概念和技术手段,如 FST(Finite State Transducer)[^4] 和 Bloom Filter 等工具帮助减少不必要的 I/O 开销。 以下是简化版 Python 实现的一个模拟版本: ```python from collections import defaultdict def build_inverted_index(documents): inverted_index = defaultdict(list) for doc_id, text in enumerate(documents): words = set(text.lower().split()) # Simple tokenization and lowercasing. for word in words: if not any(char.isdigit() for char in word): # Exclude numbers as tokens here. inverted_index[word].append(doc_id) return dict(inverted_index) documents = [ "Elasticsearch is a powerful search engine", "Elasticsearch uses inverted index", "Search engines use indexes" ] inverted_index_example = build_inverted_index(documents) print(inverted_index_example) ``` 此脚本展示了如何手动建立一个小规模的倒排索引实例。实际应用当中,Lucene/Elasticsearch 使用更复杂的算法和策略来进行这项工作。 #### 总结 综上所述,Elasticsearch 利用了 Lucene 提供的强大功能实现了高效的全文搜索服务,其中心环节便是依赖精心设计过的倒排索引体系。通过对大量非结构化数据的有效组织管理,最终达到了既满足实时性需求又能保持良好性能表现的目的[^3]。 ---
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值