如何生成大于内存容量的倒排索引?

简介: 将大规模文档分块,在内存中为每块构建倒排索引并写入磁盘临时文件,再通过多路归并合并有序临时文件,生成全局有序的倒排索引。该过程类似MapReduce思想,可分布式处理,高效构建超大倒排索引。

我们先来回顾一下,对于能够在内存中处理的小规模的文档集合,我们是如何生成基于哈希表的倒排索引的。步骤如下:

  1. 给每个文档编号,作为它们的唯一标识,并且排好序;
  2. 顺序扫描每一个文档,将当前扫描的文档中的所有内容生成 < 关键字,文档 ID,关键字位置 > 数据对,并将所有的 < 关键字,文档 ID,关键字位置 > 这样的数据对,都以关键字为 key 存入倒排表(位置信息如果不需要可以省略);
  3. 重复第 2 步,直到处理完所有文档。这样就生成一个基于内存的倒排索引。

对于大规模的文档集合,如果我们能将它分割成多个小规模文档集合,是不是就可以在内存中建立倒排索引了呢?这些存储在内存中的小规模文档的倒排索引,最终又是怎样变成一个完整的大规模的倒排索引存储在磁盘中的呢?这两个问题,你可以先思考一下,然后我们一起来看工业界是怎么做的。

首先,搜索引擎这种工业级的倒排索引表的实现,会比我们之前学习过的更复杂一些。比如说,如果文档中出现了「极客时间」四个字,那除了这四个字本身可能被作为关键词加入词典以外,「极客」和「时间」还有「极客时间」这三个词也可能会被加入词典。因此,完整的词典中词的数量会非常大,可能会达到几百万甚至是几千万的级别。并且,每个词因为长度不一样,所占据的存储空间也会不同。

所以,为了方便后续的处理,我们不仅会为词典中的每个词编号,还会把每个词对应的字符串存储在词典中。此外,在 posting list 中,除了记录文档 ID,我们还会记录该词在该文档中出现的每个位置、出现次数等信息。因此,posting list 中的每一个节点都是一个复杂的结构体,每个结构体以文档 ID 为唯一标识。完整的倒排索引表结构如下图所示:

那么,我们怎样才能生成这样一个工业级的倒排索引呢?

首先,我们可以将大规模文档均匀划分为多个小的文档集合,并按照之前的方法,为每个小的文档集合在内存中生成倒排索引。

接下来,我们需要将内存中的倒排索引存入磁盘,生成一个临时倒排文件。我们先将内存中的文档列表按照关键词的字符串大小进行排序,然后从小到大,将关键词以及对应的文档列表作为一条记录写入临时倒排文件。这样一来,临时文件中的每条记录就都是有序的了。

而且,在临时文件中,我们并不需要存储关键词的编号。原因在于每个临时文件的编号都是局部的,并不是全局唯一的,不能作为最终的唯一编号,所以无需保存。

我们依次处理每一批小规模的文档集合,为每一批小规模文档集合生成一份对应的临时文件。等文档全部处理完以后,我们就得到了磁盘上的多个临时文件。

那磁盘上的多个临时文件该如何合并呢?这又要用到我们熟悉的 多路归并技术 了。每个临时文件里的每一条记录都是根据关键词有序排列的,因此我们在做多路归并的时候,需要先将所有临时文件当前记录的关键词取出。如果关键词相同的,我们就可以将对应的 posting list 读出,并且合并了。

如果 posting list 可以完全读入内存,那我们就可以直接在内存中完成合并,然后把合并结果作为一条完整的记录写入最终的倒排文件中;如果 posting list 过大无法装入内存,但 posting list 里面的元素本身又是有序的,我们也可以将 posting list 从前往后分段读入内存进行处理,直到处理完所有分段。这样我们就完成了一条完整记录的归并。

每完成一条完整记录的归并,我们就可以为这一条记录的关键词赋上一个编号,这样每个关键词就有了全局唯一的编号。重复这个过程,直到多个临时文件归并结束,这样我们就可以得到最终完整的倒排文件。

这种 将大任务分解为多个小任务,最终根据 key 来归并 的思路,其实和分布式计算 Map Reduce 的思路是十分相似的。因此,这种将大规模文档拆分成多个小规模文档集合,再生成倒排文件的方案,可以非常方便地迁移到 Map Reduce 的框架上,在多台机器上同时运行,大幅度提升倒排文件的生成效率。那如果你想了解更多的内容,你可以看看 Google 在 2004 年发表的经典的 map reduce 论文,论文里面就说了使用 map reduce 来构建倒排索引是当时最成功的一个应用。

相关文章
|
网络协议 关系型数据库 MySQL
MySQL 设置白名单的详细步骤
要为MySQL设置白名单,需要执行以下步骤: 1. 登录到MySQL服务器的命令行或图形界面客户端。 2. 选择要设置白名单的数据库。可以使用以下命令进入MySQL命令行界面: ``` mysql -u <username> -p ``` 3. 创建一个包含需要允许访问的IP地址的表。你可以使用以下命令进行创建: ``` CREATE TABLE whitelist ( id INT NOT NULL AUTO_INCREMENT, ip_address VARCHAR(45) NOT NULL, PRIMARY KEY (
4244 1
|
6月前
|
人工智能 安全 前端开发
Team 版 OpenClaw:HiClaw 开源,5 分钟完成本地安装
HiClaw 基于 OpenClaw、Higress AI Gateway、Element IM 客户端+Tuwunel IM 服务器(均基于 Matrix 实时通信协议)、MinIO 共享文件系统打造。
11649 53
|
8月前
|
测试技术 API
小而强,GLM-4.7-Flash开源
GLM-4.7-Flash正式开源,30B总参、3B激活参数,兼顾性能与效率,支持免费调用。在编程、中文写作、翻译等多场景表现优异,已上线智谱平台,替代GLM-4.5-Flash,提供全新轻量化部署选择。
2910 1
|
10月前
|
人工智能 IDE Java
我们从零开始实现了一个cursor的codebase功能(踩了很多RAG的坑)
VoidMuse 是一个以学习为目标的开源AI IDE插件,支持IntelliJ IDEA与VS Code,集成20+优秀开源组件,助力开发者在实践中掌握AI工程化技术。本文深入解析其基于混合检索的Codebase实现,涵盖向量化、索引构建与检索优化,助你真正理解并应用Function Call等核心技术。
1451 5
我们从零开始实现了一个cursor的codebase功能(踩了很多RAG的坑)
|
9月前
|
消息中间件 存储 监控
实时数据有哪些特点?企业该如何管理好实时数据?
企业正从“事后看”转向“实时看”数据,实时数据要求秒级甚至毫秒级响应,具备持续流入、价值衰减快、流量突增等特点。管理好它需构建四大能力:流式处理架构、全链路监控、分层服务与业务闭环。建议从痛点场景试点,逐步打造可复用的实时数据体系。
|
11月前
|
机器学习/深度学习 PyTorch 算法框架/工具
python torch基础用法
本教程系统讲解PyTorch基础,涵盖张量操作、自动求导、神经网络构建、训练流程、GPU加速及模型保存等核心内容,结合代码实例帮助初学者快速掌握深度学习开发基础,是入门PyTorch的实用指南。
945 6
|
自然语言处理 IDE 开发工具
5分钟完成手势识别项目!CodeBuddy的Craft模式让传统编程方法沦为古董?
本文介绍了使用CodeBuddy快速开发手势识别程序的方法。首先安装Python 3.9.13并配置VS Code环境,接着通过pip安装依赖库`mediapipe`和`opencv-python`。利用CodeBuddy的Craft模式,仅需输入自然语言描述即可生成基础代码,经过简单调整后即可运行。代码实现了四种手势识别(OK、竖大拇指、握拳、张开手掌),并通过摄像头实时展示结果。尽管电脑摄像头像素较低,但识别效果良好。本文旨在帮助读者了解CodeBuddy的强大功能,并激发更多创意应用。
1117 20
|
缓存 网络协议 UED
深度解析HTTP协议从版本0.9至3.0的演进和特性。
总的来说,HTTP的演进是互联网技术不断发展和需求日益增长的结果。每一次重要更新都旨在优化性能,增进用户体验,适应新的应用场景,而且保证了向后兼容,让互联网的基础架构得以稳定发展。随着网络技术继续进步,我们可以预期HTTP协议在未来还会继续演化。
1204 0
|
敏捷开发 机器学习/深度学习 人工智能
需求重复、碎片化、无追溯?2025年智能化需求管理工具的关键应用
本文系统梳理需求管理工具从文档管理到AI驱动的四代技术演进,解析现代智能系统的核心功能架构与技术实现,并基于六维评估模型对比主流工具优劣。结合四阶段实施方法论与典型问题解决方案,为企业选型与落地提供全面指导。
602 0
抖音直播间刷屏打字发言脚本,全自动弹幕插件发广告插件,按键精灵智能防风控版
这是一款用于直播间批量发送弹幕信息的插件源码,可实现自动刷屏、虚拟欢迎与持续点赞功能。通过预设广告文字和随机话术,模拟真实用户行为以规避风控