Zvec Logo

倒排索引

倒排索引是一种用于存储和组织信息的数据结构,用以实现高效的基于值的搜索与检索

它广泛应用于数据库系统、搜索引擎和分析平台中,用于加速过滤操作和关键词匹配

何时使用倒排索引

当你的工作负载涉及频繁的基于特定字段值的查找时,应使用倒排索引。它在以下场景中表现出色:

  • ✅ 精确值过滤:
    • status = "active"
    • category IN ("electronics", "books")
  • ✅ 范围查询:
    • age > 25
  • ✅ 文本模式匹配:
    • 前缀匹配:product_name LIKE "Wireless%"
    • 后缀匹配:email LIKE "%@engineering.company.com"
  • ✅ 数组或集合成员查询:
    • 包含任一:tags CONTAIN_ANY ["sport", "music"]
    • 包含全部:permissions CONTAIN_ALL ["read", "write"]

工作原理

假设你正在整理一个食谱 Collection。每个食谱是一个 document,包含结构化字段 cuisineauthorurl

Doc IDCuisineAuthorURL
1ItalianJulia Chenhttps://cooking.com/italian-pasta-carbonara
2ThaiLiam Tranhttps://cooking.com/thai-basil-42
3MexicanElena Gomezhttps://cooking.com/mexican-pork-chicken-65
4ItalianMarco Rossihttps://cooking.com/italian-pizza-37
5ItalianMarco Rossihttps://cooking.com/italian-pasta-20
6ChineseJulia Chenhttps://cooking.com/chinese-spicy-hot-pot

常规的("正向")视角的问题是:

Document #1 包含哪些值? → Cuisine: Italian, Author: Julia Chen

倒排索引将这个映射反转。它回答的是:

哪些 Document 包含值 Italian? → [1, 4, 5]

为了实现快速查找,我们对频繁被搜索的字段(如 cuisineauthor)构建倒排索引。

倒排索引:cuisine

CuisineDoc IDs
Italian[1, 4, 5]
Thai[2]
Mexican[3]
Chinese[6]

倒排索引:author

AuthorDoc IDs
Julia Chen[1, 6]
Liam Tran[2]
Elena Gomez[3]
Marco Rossi[4, 5]

有了这些索引,查询变得极其高效 ✨:

  • "查找所有意大利菜谱" → 在 cuisine 索引中查找 "Italian" → [1, 4, 5]
  • "查看 Marco Rossi 的菜谱" → 在 author 索引中查找 "Marco Rossi" → [4, 5]
  • "查找 Julia Chen 的意大利菜谱" → 取交集 [1, 4, 5][1, 6][1]

我们不对 url 建立索引,因为它很少用于查询。对其建立索引会浪费存储空间并减慢写入速度,而收益甚微。一旦我们有了 Document ID,可以直接从原始数据中获取其 url

为什么叫"倒排"?

因为它将标准映射进行了反转:

方向映射
正向Document ID → 词项列表
倒排词项 → Document ID 列表

这种反转使得基于关键词的搜索变得高效。无需检查每个 Document 是否包含查询词项,而是直接跳转到该词项并立即获取所有匹配的 Document。

权衡

虽然倒排索引功能强大,但也有一定代价:

  • ⚠️ 存储开销:索引需要额外的存储空间。
  • ⚠️ 写放大:每次写操作 — INSERTUPSERTUPDATE — 都需要维护索引,增加了写入延迟和 I/O 负载。

目录