想象你在厨房里,想做一道“小笼包”。家里有几十本菜谱,你怎么快速找到所有包含“小笼包”做法的菜谱?最笨的办法是一本一本地翻,每次都找遍全书。聪明的厨师会翻开菜谱后面的“食材索引”——按食材名字排列,每个食材后面跟着一串页码。你只要查“小笼包”三个字,立刻就知道哪些页有它的菜谱。 搜索引擎做的事一模一样。你有上亿篇网页文档,用户输入“小笼包做法”,系统不可能把每篇文章从头读到尾。它提前建立了一份“网页食材索引”:把每篇文章里出现过的词整理出来,然后反向记录“每个词出现在哪些文章中”。这份索引,就是倒排索引。 这套思维贯穿信息检索的方方面面。无论是 Google 的网页搜索、Elasticsearch 里的全文检索,还是大模型外挂知识库的 RAG 系统,底层都离不开它。这篇文章从零开始,用一个菜谱比喻讲透倒排索引的数据结构、构建过程、查询原理和工程优化。

岗位关联

学懂倒排索引,你就掌握了搜索引擎、信息检索和 RAG 系统最核心的底层架设,是走向检索工程师和 AI 应用开发者的必修一课。

目录
  1. 可视化演示
  2. 为什么需要倒排索引
  3. 词典与倒排列表:索引的两大支柱
  4. 三步构建倒排索引
  5. 查询匹配:从关键词到答案
  6. 索引压缩:让索引更苗条
  7. 应用实践:搜索引擎与 RAG
  8. 性能调优:让检索更快
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示倒排索引词典与链表结构、索引构建流水线、AND查询倒排链表交集运算。切换模式查看搜索引擎底层基石的核心机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

倒排结构:词到文档反向映射 词典存储所有词项及其元信息 每个词项指向包含该词的文档链表 term → [doc1, doc3, doc5] 反向映射将正向文档-词关系反转为词-文档关系

为什么需要倒排索引

菜谱书的“食材索引”并非一开始就存在。最早的厨娘记录菜谱,用的是“每道菜用什么食材”的正向方式:翻开宫保鸡丁那页,写着鸡肉、花生、黄瓜。这本“正排菜谱”看起来顺手,但一旦你想反过来找“有哪些菜用了鸡肉”,就必须把整本书从头翻到尾。更麻烦的是,菜谱越多,翻书的时间就越长,最终长到无法忍受。

信息检索领域也经历了同样的迷茫。每篇文档都包含一串词——这是“文档到词”的正排结构。然而用户搜索时,输入的是词,想知道的是“哪些文档包含这个词”。提问方向正好和存储方向相反。如果文档数量只有几十篇,暴力遍历还能接受;但到了互联网这种上亿篇的规模,全量扫描的成本就成了灾难。

正排索引(Forward Index)形如:Doc1 → 苹果、香蕉、西瓜;Doc2 → 苹果、西瓜。要查询“苹果”在哪些文档里,必须遍历所有文档,读完整篇内容才能确认。倒排索引则把方向反过来:词 → 文档列表。苹果 → Doc1、Doc2。查询时只需在词典里一步定位,检索时间只与“这个词出现在多少篇文档中”有关,和文档总量彻底解耦。

正如表格里的页码,倒排索引把“我在哪道菜里”变成“菜在哪些页”。当菜谱有几万本时,这两种方式的差距是天壤之别——这正是搜索引擎能以毫秒级应答的原因。

T正排=O(N×L),T倒排=O(k)T_{\text{正排}} = O(N \times L), \quad T_{\text{倒排}} = O(k)
正排查询要翻遍 N 篇文档、每篇平均看 L 个词;倒排查询只需定位词条,沿着长度 k 的倒排列表走一遍。
  1. 全表扫描时间正排查询的时间等于文档数乘以每篇平均词数,文档越多越慢。
    T正排=O(N×L)T_{\text{正排}} = O(N \times L)
  2. 倒排查询时间查询时间只与词对应的文档数量 k 有关,与总文档数 N 无关。
    T倒排=O(k)T_{\text{倒排}} = O(k)

词典与倒排列表:索引的两大支柱

食材索引页看起来就是一张两栏表格:左栏是食材名,右栏是一串参考页码。左栏叫“词典”,右栏叫“倒排列表”。词典里装着菜谱中出现过的所有食材名,按字母顺序排列;倒排列表则是每个食材名后面跟着的“页码集合”——对应到搜索引擎里,就是“文档 ID 集合”。

技术上有几个关键概念需要分清。词典(Term Dictionary)存储所有出现过且去重后的词条,通常会排序,方便二分查找;倒排列表(Posting List)记录包含该词的所有文档编号;文档频率(Document Frequency)指出现某个词的文档数量,词越常见,df 越大;位置信息(Positions)记录词在每篇文档中出现的位置偏移,用于短语查询和邻近匹配。

食材“鸡肉”的索引写下“第5页、第12页、第30页”——每一个页码都是一个“文档号”,整条记录就是“倒排列表”。数据结构的本质并不神秘,神秘的是它带来的效率革命。

Posting(t)=[docID1,docID2,…,docIDk]Posting(t) = [docID_1, docID_2, \dots, docID_k]
词条 t 的倒排列表就是一组文档编号,按从小到大排列。
  1. 倒排列表词条 t 对应的文档编号列表,记录所有包含 t 的文档。
    Posting(t)Posting(t)
  2. 文档编号docID 是每篇文档的唯一编号,通常从 0 开始递增分配。
    docIDidocID_i
  3. 文档频率倒排列表的长度就是文档频率,值越大说明词越热门。
    df(t)=∣Posting(t)∣df(t) = |Posting(t)|

三步构建倒排索引

写食材索引是笨功夫:拿一本空白笔记本,逐本翻阅菜谱,每遇到“鸡肉”就往鸡肉那一行补个页码。构建倒排索引也是同样的流程,只不过把“翻菜谱”换成了“扫文档”。第一步是分词处理,把连续的文本切成独立的词条。英文靠空格就能切分,中文则需要专门的分词器,比如把“我喜欢苹果”切成“我/喜欢/苹果”。

第二步是文档编号,给每篇文档分配一个自增 ID,它就是将来倒排列表里存的那个“页码”。第三步是词典与倒排列表的填充:逐个词扫描,遇到新词就把它加入词典;遇到已经在词典里的词,就把当前文档编号追加到它的倒排列表末尾。全部文档扫描完毕,一份可用的倒排索引就诞生了。

真实工程中还会引入索引合并:新文档到来时先生成小的“增量索引段”,后台再定期把小段合并成大段。这样做可以避免每来一篇文档就重写整个索引,也方便清理删除的文档,是 Lucene、Elasticsearch 等搜索引擎的标准做法。

读完十本菜谱,食材索引也写好了。之后每来一道新菜谱,只需在对应食材的那一行补上新页码,完全不用重写整本索引。这种增量构建的思路,让搜索引擎面对海量新内容也能从容更新。

Posting(w)←Posting(w)∪{d}Posting(w) \gets Posting(w) \cup \{d\}
每处理一篇文档 d,就把 d 的编号并入它包含的每个词 w 的倒排列表中。
  1. 词条来源词 w 是文档 d 经过分词后得到的一个词条。
    w∈Doc(d)w \in Doc(d)
  2. 追加文档编号把文档号 d 并入 w 的倒排列表,这就是构建的核心操作。
    Posting(w)←Posting(w)∪{d}Posting(w) \gets Posting(w) \cup \{d\}

查询匹配:从关键词到答案

用户想吃“既要有小笼包、又有杭州风味”的菜。你翻开食材索引:小笼包——第3、8页;杭州——第3、9、20页。两组页码取交集,第3页同时满足两个条件——这就是 AND 查询。查单个词更简单,直接在词典里定位,整条倒排列表就是候选文档集合。

实际查询匹配的算法也完全是集合运算。单词查询:在词典中二分或哈希找到词条,拿出整条倒排列表。AND 查询:两个倒排列表都已按文档 ID 升序排列,用两个指针从头同时移动,编号相等就输出,编号小的指针优先前进,一轮比较完成求交,时间复杂度是 O(len(A)+len(B))。OR 查询:同样用双指针,编号小的先进入结果,相同则同时前进,完成求并。短语查询则需要利用位置信息,判断两个词在文档中是否相邻出现。

页码取交集比一页页翻书快得多,倒排索引让复杂的多词查询变成简单的集合运算。无论是 Google 还是 Elasticsearch,查询内核本质都是在做这些集合操作,这正是倒排索引“快”到极致的秘密。

R={d∣d∈P(q1)∧d∈P(q2)}R = \{ d \mid d \in P(q_1) \wedge d \in P(q_2) \}
同时包含词 q1 和词 q2 的文档集合,是两个倒排列表的交集。
  1. 词条对应的文档集合P(q1) 表示包含词 q1 的所有文档组成的集合。
    P(q1)P(q_1)
  2. 成员关系d ∈ P(q1) 说明文档 d 在集合中,也就是 d 包含 q1。
    d∈P(q1)d \in P(q_1)
  3. 求交集∧ 表示“并且”,两边条件同时满足的 d 才是最终结果。
    d∈P(q1)∧d∈P(q2)d \in P(q_1) \wedge d \in P(q_2)

索引压缩:让索引更苗条

食材索引的页码越来越长:“第3页、第7页、第8页、第15页……”密密麻麻的页码看着都费劲。聪明的索引编写者记录差值:"3、+4、+1、+7……"每个数字都大幅变小,写起来省地方,读起来也不费劲。索引压缩的原理同样如此。

真实搜索引擎的文档 ID 可能大到几十亿,直接存整数要占 4 字节甚至 8 字节。工程上常用四种压缩手法。增量编码(Delta Encoding):倒排列表按文档 ID 升序排列,只存相邻文档号之间的差值,把大数变成小数。变长编码(Varint Coding):数字小时只占 1 字节,数字大时多用几个字节,按需分配。位图压缩(Bitmap):用 01 位串标记文档集合,适合文档号密集的场景。跳表指针(Skip Pointer):在倒排列表上另外建一层稀疏索引,归并时可以跳过大量不相干的区间。

压缩不是偷工减料,而是让索引更小、更省内存。正如"3、+4、+1、+7"让食材索引变得轻便易翻,压缩后的倒排列表让几十亿篇文档的索引也能稳稳装进内存,查询时免去磁盘 IO,速度不降反升。

Δi=docIDi−docIDi−1\Delta_i = docID_i - docID_{i-1}
相邻文档 ID 的差值往往远小于文档 ID 本身,存差值可以大幅减少存储空间。
  1. 当前文档号docID_i 是倒排列表中第 i 个文档的编号。
    docIDidocID_i
  2. 上一个文档号docID_{i-1} 是前一个文档的编号,列表已按升序排列。
    docIDi−1docID_{i-1}
  3. 求差值两者相减得到增量,由于文档号紧凑,差值通常是个很小的数。
    Δi=docIDi−docIDi−1\Delta_i = docID_i - docID_{i-1}

应用实践:搜索引擎与 RAG

拿到食材索引不等于菜品排名。餐厅点单还要结合“最受欢迎”——倒排索引解决了“有哪些候选”的问题,但用户往往只关心前十条结果,这就需要排序。经典做法是 TF-IDF 打分:词频(tf)表示词在文中出现的次数,逆文档频率(idf)表示词的稀缺程度。词在文档里出现越多、同时在整个文档集合里越稀有,这文档与查询的相关度就越高。

在此基础上还衍生出大量工程实践。查询扩展:用户输入“苹果手机”时,自动把"iPhone"也加入查询,召回更多候选。RAG 混合检索:大模型问答系统先用倒排索引按关键词快速粗筛出几百篇候选文档,再用向量检索做语义精排,兼顾字面匹配和语义理解。实时更新:新文章一发布,立刻生成增量段并入索引,让搜索结果和新闻同步。

食材索引回答了“有哪些菜”,排序回答了“先推荐哪道菜”。餐馆既要翻索引快,也要会判断招牌菜——搜索引擎就是这样一个既懂检索又懂排序的“老厨师”。

w=tf×log⁡Ndfw = tf \times \log \frac{N}{df}
词频越高、文档越稀有,这个词对文档的贡献权重就越大。
  1. 词频tf 表示词 t 在文档 d 中出现的次数,出现越多说明文档越相关。
    tftf
  2. 逆文档频率N 是文档总数,df 是包含该词的文档数,log 后值越大说明词越稀有。
    log⁡Ndf\log \frac{N}{df}
  3. 权重乘积词频高且文档稀有,综合权重才高;常见词会被自然压低权重。
    w=tf×log⁡Ndfw = tf \times \log \frac{N}{df}

性能调优:让检索更快

高峰时段餐厅点单,厨师不会真的等顾客点了菜再跑去仓库找食材。他们会把常用食材备在手边,后厨分成几个灶台同时炒菜,小订单还拼成大订单一起出。倒排索引的性能优化思路——缓存、分片、内存索引、段合并——与后厨管理如出一辙。

缓存机制:热门查询词的结果提前放进内存,命中后毫秒返回,完全跳过索引查找,就像“招牌菜提前备好料”。分片并行:索引按文档范围切分到多台机器,各节点并行检索自己的分片,最后把局部结果合并,就像多个灶台同时开工。内存索引:热数据放内存(如 Lucene 的 FST 词典),冷数据落磁盘,内存不够就用操作系统的页缓存。段合并:新增文档生成小索引段,后台定期把小段合并成大段,减少文件句柄数,降低查询时需要扫描的段数量。

后厨分工合作、食材提前备好,出菜速度自然快。搜索引擎也把“备菜”的功夫下在平时——索引构建、压缩、缓存、分片——才能在用户按下回车键的瞬间,把答案端上桌。

R=R1∪R2∪⋯∪RnR = R_1 \cup R_2 \cup \cdots \cup R_n
每个分片返回自己的候选结果集,合并所有分片结果就是最终答案。
  1. 局部结果分片 i 在它负责的文档子集上查询,得到局部结果 R_i。
    RiR_i
  2. 合并全部结果所有分片的局部结果取并集,得到完整返回集。
    R=⋃i=1nRiR = \bigcup_{i=1}^{n} R_i

AI 应用场景

Elasticsearch 全文检索

阶段:数据存储与检索

解决的问题:电商平台的商品搜索,如果直接在数据库里用 LIKE '%连衣裙%' 做模糊查询,百万级商品数据会全表扫描,响应时间轻松超过一秒。Elasticsearch 在写入时对商品标题做分词并构建倒排索引,查询时从词典定位候选商品,毫秒级返回,彻底告别全表扫描。

具体案例:用户在某电商 App 输入“红色连衣裙”,后台 ES 的倒排索引先按关键词召回数万候选,再结合销量、评分、价格等条件排序,最终把最相关的 20 个商品展示在首页。

RAG 混合检索

阶段:检索增强生成(RAG)

解决的问题:纯向量检索擅长语义匹配,但对“专有名词、精确 ID、代码函数名”这类字面匹配场景经常失灵。倒排索引按关键词精确匹配,恰好能补充向量检索的盲区,两者结合形成“粗排 + 精排”的混合检索管道。

具体案例:企业内部知识库问答机器人,先通过倒排索引把用户问题里的关键词(如“报销流程”“差旅标准”)匹配到候选文档,再把这些候选文档交给向量模型做语义精排,最后喂给大模型生成回答。这样既保证召回率,又压低了幻觉。

MySQL 全文索引

阶段:数据库全文搜索

解决的问题:博客系统要搜索文章正文,用 LIKE 无法利用索引,数据量大时慢得难以接受。MySQL 的 FULLTEXT 索引底层就是倒排索引,对文本列先分词再建立词到行的映射。

具体案例:某内容平台的文章表有百万行,需要搜“神经网络”相关文章。使用 FULLTEXT 索引后,用户输入关键词,MySQL 直接查倒排列表定位到匹配行,响应时间从秒级降到百毫秒级。

Python 演示

python72 行
# -*- coding: utf-8 -*-"""简易倒排索引:构建与布尔查询"""from collections import defaultdict  class InvertedIndex:    def __init__(self):        self.postings = defaultdict(list)  # 词 -> 文档ID列表     def build(self, corpus):        for doc_id, text in enumerate(corpus):            for term in set(text.split()):                self.postings[term].append(doc_id)     def query(self, word):        return self.postings.get(word, [])  def boolean_and(idx, q1, q2):    """AND查询:双指针归并两个倒排列表"""    a, b = idx.query(q1), idx.query(q2)    i = j = 0    result = []    while i < len(a) and j < len(b):        if a[i] == b[j]:            result.append(a[i])            i += 1            j += 1        elif a[i] < b[j]:            i += 1        else:            j += 1    return result  def boolean_or(idx, q1, q2):    """OR查询:双指针求并集"""    a, b = idx.query(q1), idx.query(q2)    i = j = 0    result = []    while i < len(a) and j < len(b):        if a[i] == b[j]:            result.append(a[i])            i += 1            j += 1        elif a[i] < b[j]:            result.append(a[i])            i += 1        else:            result.append(b[j])            j += 1    result.extend(a[i:])    result.extend(b[j:])    return result  if __name__ == "__main__":    corpus = [        "苹果 香蕉 西瓜",        "苹果 西瓜",        "香蕉 西瓜 葡萄",        "苹果 香蕉 葡萄",    ]    idx = InvertedIndex()    idx.build(corpus)     for term in sorted(idx.postings):        print(f"{term}: {idx.postings[term]}")     print("苹果 AND 香蕉:", boolean_and(idx, "苹果", "香蕉"))    print("苹果 OR 香蕉:", boolean_or(idx, "苹果", "香蕉"))    print("葡萄 未收录:", idx.query("榴莲"))
  1. self.postings = defaultdict(list)用字典存储“词 → 文档列表”的映射,默认值为空列表。
  2. for doc_id, text in enumerate(corpus):遍历语料,每篇文档获得一个自增编号。
  3. for term in set(text.split()):按空格分词并去重,避免同一词重复入列。
  4. self.postings[term].append(doc_id)核心构建操作:把文档号追加到词的倒排列表。
  5. def boolean_and(idx, q1, q2):实现 AND 查询,核心是双指针归并两个升序列表。
  6. while i < len(a) and j < len(b):两个指针同时遍历,每次循环至少移动一个指针,线性时间复杂度。
  7. elif a[i] < b[j]: i += 1编号小的一方不可能在对方列表中匹配到相同值,直接跳过。
  8. result.extend(a[i:]); result.extend(b[j:])归并结束后把剩余元素全部加入结果。

常见误区

误区听名字里有“倒”字,以为倒排索引就是把文档内容倒序存储,或者把文档链表反转,跟“反转链表”“倒序输出”是一回事。

正解倒排索引不是改变文档的存储顺序,而是改变“映射方向”。正排索引是“文档 → 词列表”,倒排索引是“词 → 文档列表”,它反转的是“包含关系”的方向。就像食材索引没有改变菜谱的页码顺序,只是额外建立了一个按食材查页码的目录。

为何常见:术语里的“倒排”容易让人望文生义,加上链表反转等数据结构概念先入为主,初学者很容易把“方向反转”误解成“顺序反转”。

误区建完倒排索引之后就不用管了,新增文档、删旧文章都不影响,索引会自己保持最新。

正解倒排索引必须与文档集合保持一致。新增文档要增量更新对应词的倒排列表,删除文档要从倒排列表移除对应文档 ID,否则搜索会出现“连点菜谱都找不到”的脏数据。工程上正是为此设计了“增量段 + 后台段合并”机制。

为何常见:学习阶段使用一次性构建的静态语料,看不到数据更新的场景,容易忽视真实搜索引擎中“动态性”这个核心挑战。

误区既然倒排索引查询这么快,那所有场景都应该用倒排索引,正排索引已经被淘汰了。

正解倒排索引擅长“关键词 → 文档”的检索,但“文档 → 词”的遍历场景(如文档指纹计算、全文去重)反而用正排索引更自然。真实系统往往是正排、倒排共存:倒排做查询,正排存原始词列。食材索引再方便,也不能替代菜谱本身。

为何常见:单一指标地比较两种结构,忽略了“适用场景不同”这一前提,初学者容易把局部优势推广成全局结论。

误区压缩肯定要解压,解压肯定慢,所以索引压缩是“用时间换空间”,压缩率越高查询越慢。

正解倒排索引压缩后数据量更小,原本装不进内存的索引可以装进内存,原本要读多个磁盘块的列表只需读一个块。CPU 解压几个字节的开销远小于一次磁盘 IO,因此压缩在多数场景下反而变快。就像把食材切好备好看似多花功夫,但出菜时反而更快。

为何常见:凭直觉认为“压缩 = 解压 = 额外开销”,忽略了内存/磁盘的瓶颈远大于 CPU 计算,对现代存储层级缺少体感。

面试题

Q1. 倒排索引的核心思想是什么?

单选题 · easy

  • A.把文档按时间顺序存储
  • B.把词映射到包含它的文档列表← 正确答案
  • C.把文档中的词加密压缩
  • D.把文档复制到多个服务器

答案:B。倒排索引的核心是建立“词 → 文档列表”的映射,让查询词时直接定位文档,相当于菜谱里的食材索引;按时间排序是归档思路,加密、复制都与检索映射无关。

Q2. 倒排列表中最典型的元素是什么?

单选题 · easy

  • A.文档ID← 正确答案
  • B.文件路径字符串
  • C.用户密码
  • D.图片字节流

答案:A。倒排列表存储文档编号,用自增整数表示“哪篇文档包含这个词”,紧凑高效;文件路径过长、密码无关、图片字节流更是与检索毫不相干。

Q3. 正排索引和倒排索引之间的关系是什么?

单选题 · mid

  • A.两者完全相同
  • B.映射方向互为逆关系← 正确答案
  • C.倒排索引包含正排索引
  • D.正排索引就是倒排索引的备份

答案:B。正排是“文档 → 词”,倒排是“词 → 文档”,两者方向相反形成逆映射。就像菜谱从“菜名→食材”和食材索引从“食材→页码”,是两种视角的互逆,而不是包含或备份关系。

Q4. 构建倒排索引的第一步通常是什么?

单选题 · mid

  • A.对索引做压缩
  • B.对文档做分词处理← 正确答案
  • C.对结果加密存储
  • D.建立跨机器备份

答案:B。分词是构建索引的前置步骤,把连续文本切成语义最小单位——词条,之后才能建立词到文档的映射。压缩、加密、备份都属于构建完成后的工程优化,顺序上发生在分词之后。

Q5. 倒排索引可以直接支持哪些布尔查询?

多选题 · mid

  • A.AND(包含所有词)← 正确答案
  • B.OR(包含任意词)← 正确答案
  • C.NOT(不包含某词)← 正确答案
  • D.数值加减运算

答案:ABC。倒排列表本质上是一组文档集合,AND 是集合交集,OR 是集合并集,NOT 是集合补集,都是倒排索引在词典中找到对应词条后进行集合运算;数值加减不是文档集合运算,与倒排索引无关。

Q6. 两个升序倒排列表做 AND 查询,最高效的归并方式是?

单选题 · hard

  • A.双重循环暴力比较
  • B.哈希表存储其中一个列表
  • C.双指针同步线性扫描← 正确答案
  • D.把两个列表拼接后排序

答案:C。双指针线性扫描利用两个列表都已升序的性质,每次移动较小的指针,复杂度 O(m+n) 且无需额外空间;哈希表需要额外内存构造,双重循环和拼接排序复杂度更高,都不是最优解。

Q7. 倒排索引中“词典”存储的内容是什么?

单选题 · mid

  • A.所有文档的完整正文
  • B.所有出现过的去重词条← 正确答案
  • C.所有用户账号信息
  • D.所有历史查询记录

答案:B。词典存储语料中所有出现过的词条并去重,查询时先在词典中定位词,再取倒排列表;完整正文属于原始数据,用户信息和查询记录与索引结构无关。

Q8. 关于倒排索引的压缩技术,以下哪些说法正确?

多选题 · hard

  • A.增量编码把大文档号变成小差值← 正确答案
  • B.变长编码按数字大小灵活分配字节← 正确答案
  • C.位图用01串标记文档是否包含词← 正确答案
  • D.跳表指针能直接压缩文档内容

答案:ABC。增量编码存相邻文档 ID 的差值,变长编码按需分配字节,位图用 01 位标记文档集合,三者都是常用压缩手段。跳表指针属于查询加速结构,它加速归并,但并不压缩文档内容,因此 D 错。

Q9. 在 RAG 系统中,倒排索引通常承担什么角色?

单选题 · easy

  • A.生成最终回答文本
  • B.快速定位候选文档← 正确答案
  • C.训练大语言模型
  • D.存储知识向量

答案:B。RAG 系统先用倒排索引做关键词粗筛,快速缩小候选文档范围,再把候选交给向量精排和大模型生成回答。倒排索引负责候选召回,生成回答是 LLM 的事,训练和向量存储是另一套系统。

Q10. 关于跳表指针在倒排列表中的作用,正确的说法有?

多选题 · extreme

  • A.跳过不可能匹配的文档区间← 正确答案
  • B.加速 AND 查询的归并过程← 正确答案
  • C.替代词典完成分词操作
  • D.必须重建整个倒排列表才能使用

答案:AB。跳表指针在倒排列表上建立稀疏索引,归并时如果指针指向的文档号还小于对方当前文档号,可以整段跳过,所以 A、B 正确。跳表只是附加的加速结构,不参与分词,也不需要重建列表,C、D 错误。