图书管理员老周的桌上摊着一本翻得卷边的“词语索引本”。每个词条下密密麻麻列着书号:翻开“麦田”,写着 37 号、58 号、102 号……读者问“哪本书记载了麦田”,老周翻翻本子几秒就能作答。这个神奇的索引本,就是搜索引擎里“倒排索引”最朴素的模样。 直到某天,一位读者要“找一本写了'金色的麦田'这五个字连贯出现的书”——注意,不是分别有“金色”和“麦田”,而是它们必须肩并肩,一字不差。老周傻眼了:索引本只告诉他哪些书提过哪个词,却答不出词与词是否挨在一起。被逼无奈,老周开始给索引本“升级”:每个词条下除了书号,还要记录“这本书里的第几个词位置出现了这个词”。 这版升级后的“词语索引本”,就是位置索引。有了它,老周可以回答“金色后面的那个词是不是麦田”这样的短语查询;再放宽一点,还能回答“金色和麦田相隔不超过三个词”的近邻查询。代价是索引本厚了好几倍,老周不得不研究各种压缩技巧。本文将沿着老周的升级之路,把位置索引的结构、匹配算法、空间优化与中文场景讲个明白。
对 AI 从业者来说,短语查询与位置索引是搜索引擎、数据库全文检索、RAG 召回精排的底层基石。理解它,你才能真正读懂 Elasticsearch 的 match_phrase 为什么快、为什么贵,并在面试与系统设计中游刃有余。
可视化演示
演示位置索引的存储结构、短语查询的位置匹配算法,以及近邻查询中词项距离的计算过程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
位置索引存储结构 每个词项关联文档列表与位置数组 位置信息支持短语和近邻查询 空间开销约为基础索引2-4倍 term→[(doc,[pos1,pos2...])] 倒排表扩展位置数组记录词项出现位置
倒排索引回顾
老周的“词语索引本”其实有讲究:他不是把所有藏书从头翻到尾,而是先编一本“词典”——把馆里所有书里出现过的词去重整理成词条;每个词条下挂着“倒排表”,也就是出现过这个词的书号清单。词典加倒排表,合起来就是倒排索引。老周的管理台账,正是信息检索里最经典的数据结构。
搜索引擎的倒排索引和它一模一样。建索引时,系统把每篇文档切分成词项,统计每个词项出现在哪些文档里;查询时,用户输入的词直接在词典里查,拿到倒排表。比如查询“金色 AND 麦田”,系统分别取“金色”和“麦田”的倒排表,再做集合求交,结果就是同时包含两个词的文档。这种“两个名单对一对”的思路,就是布尔查询的合并过程。
除了文档编号,倒排表通常还会记录词频 tf(词在文档中出现了几次)和文档频率 df(有多少文档包含该词),用于后续相关性排序。两个倒排表的合并是检索的核心操作,最朴素的做法是双指针扫描:两个表都按文档号升序排列,谁小谁前进,相等就输出。
可是老周渐渐发现,这个索引本有个致命盲区:它记录的是“书号”这个粗粒度位置,而不是“书里第几个词”这个细粒度位置。读者真正想找的往往是“一句话”而不仅仅是“一个词”。于是,升级索引本迫在眉睫。
- 倒排表符号$I(\cdot)$ — 输入一个查询词,返回该词的倒排表(文档编号集合)
- 合取语义$\wedge$ — 表示“且”,两个查询词的条件必须同时满足
- 集合求交$\cap$ — 求两个倒排表共同的文档编号,得到布尔 AND 的检索结果
位置索引结构
老周在“金色”词条下加了一列小字:37 号书,出现在第 1、8、15 个词的位置;58 号书,出现在第 0、5、9 个词的位置。“麦田”词条同样处理。这相当于给每个词在书里装上了“页码行号”,原先的粗粒度书号变成了精确定位。老周的新本子,就是位置索引的雏形。
位置索引和普通倒排索引的唯一区别是:每个倒排表项不再只是一个文档编号 docID,而是“docID + 位置列表”。位置列表中的每个整数,代表词项在该文档分词后的第几个词位出现,一般从 0 开始编号。比如“金色”在 58 号书的第 0、5、9 个词位出现,就记作 [0, 5, 9]。
位置列表按照词位严格递增排列,这一点至关重要——查询时用双指针比较,两个位置值谁小谁往后走,才能在线性时间内完成相邻性检查。位置列表的长度等于该词在该文档中的出现次数,也就是词频;把所有文档所有词项的位置数相加,就得到位置索引的总规模,它大致等于语料库的总词数。
有了“页码行号”,老周回答“金色后面是不是麦田”就不再靠猜了:翻开两个词条,逐本书比对位置。不过,肉眼比对效率太低,他需要一套明确的比对规则——这就是下一节的短语匹配算法。
- 倒排表项$\mathrm{posting}(t)$ — 检索词项 t 得到的完整倒排表,是所有“文档-位置”对的集合
- 位置集合$P_{t,d}$ — 词 t 在文档 d 中所有出现位置组成的集合,k 是出现次数
- 文档限定$t \in d$ — 只为真正包含词 t 的文档记录位置,不出现的文档不进集合
- 递增排列$p_1 < p_2 < \cdots < p_k$ — 位置按词位升序存储,这是双指针合并的前提
短语匹配算法
老周像校准两串珍珠项链一样,把“金色”和“麦田”两条位置列表在同一个文档里逐位对齐:金色在第 0 个词位,那么麦田必须正好在第 1 个词位;金色在 0 和 3 有两个位置,麦田在 1 和 8,那么“0 对 1”这一对就算对上,文档命中。老周的手指在两个词条上左右滑动,就是最原始的短语匹配。
计算机里的短语查询,正是这个“位置对齐”过程的程序化。给定短语 $w_1 w_2 \cdots w_m$,先在倒排索引里查得每个 $w_j$ 的倒排表,然后对这些倒排表做文档级求交;对共同出现的文档,再用位置列表做相邻性检查:第一个词在位置 p,那么第二个词必须在 p+1,第三个词必须在 p+2,以此类推。顺序和相邻缺一不可。
实现上可以采用双指针合并。比如对两词短语,两个位置列表都从 0 号元素开始:若第二个位置等于第一个位置加 1,命中;若第二个位置更小,第二个指针后移;否则第一个指针后移。整个过程每个位置最多被访问一次,时间复杂度与位置总数成线性关系,非常高效。
老周的珍珠项链校准法完美解决了“金色麦田”;但另一位读者走来问:“找不到'金色的麦田'没关系,'金色'和'麦田'隔不超过三个字我也接受。”这就是把“紧挨着”放宽成“隔不远”——近邻查询登场了。
- 短语长度$m$ — 短语包含的词项总数,两词短语时 m = 2
- 基准位置$p_{t_1}$ — 短语首个词在文档中的某个出现位置,作为对齐基准
- 位置增量$j - 1$ — 第 j 个词必须位于基准之后第 j-1 个词位,同时保证顺序与相邻
- 全程校验$j = 1, 2, \ldots, m$ — 对短语的每个词逐一检查,全部通过才算命中
近邻查询处理
老周这次不再要求两词“手牵手”,而是允许“一个手臂的距离”:只要“麦田”出现在“金色”之后、且位置差不大于 k 个词位,就算命中。读者给了 k=3,于是“金色 的 麦田”这种中间隔着“的”的文档也能被找到。老周在索引本上比划着两列数字之间的距离,心里有了新的规则。
这就是近邻查询——短语查询的“宽松版”。它依然利用位置索引,但把“位置差恒等于 1”放宽为“位置差 ≤ k”。按方向要求不同,又分为有序近邻(第二个词必须在前一个之后)和无序近邻(两词谁先谁后无所谓)。前者适合“温故知新”这种讲究顺序的表达,后者适合“噪音污染”这种位置不敏感的同现。
实现近邻查询时,可以对两个位置列表做窗口滑扫:维护两个指针指向两词当前考察的位置,记录位置差,若差在允许范围内则命中,然后移动较前的那个指针,像一个滑动窗口沿着文档从左到右扫过。窗口滑扫只需要线性扫描两个位置列表各一次,比嵌套循环快得多。
老周的“手臂距离”规则大大提高了召回:读者想找“金色麦田”周边的话题,不必死扣字眼。但索引本也因此被查得更频繁——加上位置信息本身就体积膨胀,老周必须想想怎么给索引本“减肥”了。
- 顺序约束$p_{t_2} - p_{t_1} > 0$ — 第二个词必须排在第一个词之后,顺序不可颠倒
- 距离上界$\le k$ — 两词位置差不得超过用户设定的窗口大小 k
- 严格为正$0 <$ — 排除位置相同或逆序的非法情形,保证两词确实占据不同词位
- 无序变体$|p_{t_2} - p_{t_1}| \le k$ — 无序近邻不考虑先后,用绝对值判断距离即可
空间效率优化
升级后的索引本让老周哭笑不得:原来 300 页的本子,记完位置信息后变成了 900 页。毕竟普通倒排表每个词记一个书号,位置索引却要记下每个词在每本书里的每一次出现——总条数等于整座图书馆所有书的字数之和。这个代价,在搜索引擎里叫“索引体积膨胀”。
位置索引的体积膨胀是主要成本:位置总数约等于语料库全部文档的词语总数,通常是普通倒排表规模的数倍。工程上常用的压缩思想是“把大整数变成小整数”:位置值本身很大,但相邻位置的间隔很小,存间隔显然更省。老周很快想到了这个主意:与其写“第 3、7、12、20 个词位”,不如写“第 3 个词位,之后隔了 3 个、再隔了 4 个、再隔了 7 个”。
位置差分编码正是记录相邻位置的间隔:$g_i = p_i - p_{i-1} - 1$,减 1 是因为位置连续时间隔记为 0。由于多数文档里同一词的出现位置不会太疏,间隔值通常很小,再配合变长字节编码(小整数用 1 个字节、大整数用多个字节)就能大幅压缩。此外还有跳跃指针:倒排表每隔若干项放一个“快进点”,加速求交时一次性跳过大段无关文档。
老周用“记录间隔”这招把索引本又压回了 400 页。他正得意,一位中文系的读者走进来,抱着一本没有空格的小说:“麻烦帮我查查'金色的麦田'在哪几本书里?”老周这才意识到:中文书根本没有空格分词,他的索引本在编本子之前就卡住了。
- 参考位置$p_{i-1}$ — 列表中上一个出现位置,作为差分的参考基准
- 当前位置$p_i$ — 当前出现位置,与参考位置相减得到间隔
- 间隔修正$-1$ — 位置连续时原始差值为 1,减 1 后间隔变为 0,数值更小更易压缩
- 反向还原$p_i = p_{i-1} + g_i + 1$ — 查询时从第一个位置起累加间隔,还原全部绝对位置
中文分词应用
英文书里词与词之间有天然的空格,老周照抄空格就能编词条;可中文书里“金色的麦田”五个汉字挤在一起,如果不先切分,整个句子就会变成“金”“色”“的”“麦”“田”这样的单字。索引本是建了,却答不出“金色麦田”这种词级查询。中文搜索引擎的文档处理流水线因此多了一步:分词。
建索引前,先用分词器把连续的汉字切成词序列:“金色的麦田” → “金色 / 的 / 麦田”,然后按词建立位置索引。这样词项是词而非单字,位置编号也是词在句子中的序号。用户查询“金色麦田”时同样先分词,再把切分结果拿到索引里做短语匹配。查询改写切分让用户与文档在同一个“词序列空间”里对齐。
如果采用字级索引(以单个汉字为词项),查询“金色麦田”只是四个单字的共现,会召回“金色/的/麦田里”等大量语义无关的文档,噪声很大;词级索引更精确,但依赖分词器的词典质量,未登录词可能被切错。位置索引在中文的妙处还在于支持词级模糊命中:查询“金色麦田”分词为“金色”“麦田”,而文档“金色的麦田”分词为“金色”“的”“麦田”,词位差为 1,用近邻查询或查询改写就能灵活召回。
老周欣慰地发现,一旦中文文档完成了分词,他的位置索引本照样适用,甚至能发现“金色的麦田”与“金色麦田”两种表达之间的微妙位置关系。不过,面对浩如烟海的藏书,他也在反思:是不是每本书、每个词都值得记录精确位置?
- 查询切分$Q \mapsto \langle w_1, w_2, \ldots, w_m \rangle$ — 原始查询串被分词器映射成有序词序列
- 词序保留$\langle w_1, w_2, \ldots, w_m \rangle$ — 尖括号表示保留顺序的词序列,位置匹配依赖这个顺序
- 词典约束$w_i \in \mathcal{V}$ — 切分出的每个词必须来自词项词典,未登录词无法被正确切出
- 对齐匹配$\mathrm{pos}(w_j) = \mathrm{pos}(w_1) + (j - 1)$ — 切分后的词序列进入短语匹配,逐个与文档词位对齐
混合策略选择
老周最后总结出一条经验:对于“的”“了”“和”这种高频虚词,记录它们的位置纯属浪费纸面——几乎每页都有它们,位置列表长得吓人却几乎没有查询价值;而“金色麦田”这种固定搭配,与其查两个词再比对位置,不如直接把它当做一个词条编进索引本。这叫按词性、按频次区别对待。
这正是工业界搜索系统的常规思路:混合索引。对高频常见短语,直接建立短语索引(把整个短语作为一个词项);对一般内容,才使用位置索引支持任意短语与近邻查询;还可以做字段级索引,比如对标题字段建位置索引、对正文只建普通倒排索引。Lucene/Elasticsearch 甚至可以配置关闭位置信息,牺牲短语能力换取更小的索引体积。
空间与时间的权衡贯穿始终。位置索引让短语查询变快,但索引变大、写入变慢;关闭位置则索引瘦身,短语查询退化为词项共现查询。设计时通常结合业务:电商的“品牌+类目”短语、法律的“法条引用”场景必须开位置索引,而日志检索这种以单词过滤为主的场景可以关闭。跳跃指针、变长编码、位置截断(每个文档只保留前 K 个位置)等技巧进一步细化这个取舍。
老周的图书馆终于形成了自己的“检索手册”:高频虚词只记书号,关键词记页码行号,固定搭配直接编成新词条。搜索引擎的设计同样如此——没有银弹,只有基于数据分布与业务场景的精细权衡。
- 表长定义$N$ — 词项倒排表中的文档项总数,跳跃表建立在它之上
- 均匀采样$\sqrt{N}$ — 开平方根给出理论最优步长,平衡“跳过消费”与“比较代价”
- 取整处理$\lfloor \cdot \rfloor$ — 向下取整得到整数步长,保证跳跃点不越界
- 跳跃步长$s = \lfloor \sqrt{N} \rfloor$ — 每隔 s 个文档放一个跳跃指针,求交时可大跨度跳过无关区间
AI 应用场景
场景1:电商搜索的精准短语召回
阶段:查询理解与检索召回
解决的问题:用户在淘宝搜索“苹果手机壳”时,期望召回标题里“苹果 手机壳”连续出现、顺序一致的商品。传统倒排索引只能保证两词共现,会召回“苹果味手机壳”“苹果 手机 壳”等词序错乱或不相邻的结果;位置索引精确检查词位连续,召回精度大幅提升。
具体案例:Elasticsearch 的 match_phrase 查询就是位置索引的典型应用。用户输入“深度学习 入门”,索引记录每篇文档分词后“深度学习”与“入门”的词位,只有位置差为 1 的文档才进入候选。
场景2:RAG 知识库的短语级段落召回
阶段:检索增强生成(RAG)的召回阶段
解决的问题:问答系统常需找到文档中与问题字面高度重合的句子片段(如“新能源汽车购置税减免”)。仅靠向量检索可能召回语义相似但关键短语错位的段落;叠加位置索引的短语/近邻匹配,能有效提升回答的引用准确性。
具体案例:某法律知识库问答系统中,用户问“合同解除的法定条件”,系统先分词为“合同/解除/法定/条件”,再用近邻查询(k=2)匹配包含相近词序的条款原文,精准定位到法条段落。
场景3:新闻转载与洗稿检测
阶段:内容理解与去重
解决的问题:判断一篇文章是否转载另一篇,关键证据是“连续若干词完全一致”的片段。位置索引让系统快速找出两篇文章共享的短语窗口,比逐句比对高效得多。
具体案例:某内容平台用位置索引对百万篇新闻做 8 词以上长短语交叉匹配,命中片段占比超过 30% 即判定转载,有效识别洗稿账号。
Python 演示
"""位置索引:用"书页坐标"实现短语查询与近邻查询"""class PositionalIndex: def __init__(self): self.index = {} # 词项 -> {文档ID: [位置列表]} self.doc_lengths = {} # 文档ID -> 词数 def add_document(self, doc_id, tokens): """向索引中添加一篇文档,记录每个词项的出现位置""" self.doc_lengths[doc_id] = len(tokens) for pos, token in enumerate(tokens): if token not in self.index: self.index[token] = {} if doc_id not in self.index[token]: self.index[token][doc_id] = [] self.index[token][doc_id].append(pos) def phrase_query(self, phrase): """短语查询:词项必须按顺序连续出现""" if not phrase: return [] if any(t not in self.index for t in phrase): return [] common = set(self.index[phrase[0]].keys()) for t in phrase[1:]: common &= set(self.index[t].keys()) results = [] for doc_id in sorted(common): if self._aligned(phrase, doc_id): results.append(doc_id) return results def _aligned(self, phrase, doc_id): """检查短语在文档中是否存在连续对齐的位置""" for p in self.index[phrase[0]][doc_id]: ok = True for j in range(1, len(phrase)): if (p + j) not in self.index[phrase[j]][doc_id]: ok = False break if ok: return True return False def proximity_query(self, w1, w2, k, ordered=True): """近邻查询:w1 与 w2 的距离不超过 k 个词位""" if w1 not in self.index or w2 not in self.index: return [] results = [] for doc_id in sorted(set(self.index[w1]) & set(self.index[w2])): hit = False for a in self.index[w1][doc_id]: for b in self.index[w2][doc_id]: gap = b - a if (ordered and 0 < gap <= k) or (not ordered and abs(gap) <= k): hit = True break if hit: break if hit: results.append(doc_id) return results if __name__ == "__main__": docs = { 0: ["金色", "的", "麦田", "真", "美"], 1: ["金色", "麦田", "里", "有", "丰收"], 2: ["麦田", "守望", "者", "金色", "麦田"], } pi = PositionalIndex() for doc_id, tokens in docs.items(): pi.add_document(doc_id, tokens) print("位置索引:", pi.index) print("短语查询 [金色, 麦田]:", pi.phrase_query(["金色", "麦田"])) print("近邻查询 金色~麦田(有序,k=2):", pi.proximity_query("金色", "麦田", 2, ordered=True))
if token not in self.index:判断词项是否首次出现,首次则新建词条,相当于老周在索引本上开新页self.index[token][doc_id].append(pos)把出现位置记入位置列表,这就是位置索引的“页码行号”common &= set(self.index[t].keys())对多个词项的倒排表做集合求交,只保留同时包含所有查询词的文档if (p + j) not in self.index[phrase[j]][doc_id]:校验短语第 j 个词是否恰好位于首个词位置之后 j 个词位,完成“珍珠项链对齐”gap = b - a计算两个词的位置差,它是近邻查询的核心度量if (ordered and 0 < gap <= k) or (not ordered and abs(gap) <= k):有序与无序近邻的统一判定:顺序正确且距离不超窗口就算命中
常见误区
误区在很多初学者的理解里,短语查询不过是两个词项倒排表求交集,只要文档同时出现了两个词,就认为结果命中,根本不看词序和间距。
正解短语查询严格得多。它要求词项按查询顺序连续出现:两词短语的位置差必须恰好等于 1,多词短语则要求每个词的位置严格递增 1。如果文档是“金色的麦田”,搜“金色麦田”就搜不到,因为中间隔着一个“的”。用老周的比喻:倒排表求交只是“两个人都在图书馆里”,短语查询要求“两个人手牵着手排在同一列队伍里”。
为何常见:倒排索引的教学通常先从布尔查询讲起,布尔 AND 恰好就是集合求交,初学者容易把“共现”误当成全部,忽略了位置这一维信息。
误区许多人以为位置索引里存的是“这个词从文档第几个字节开始”,毕竟字节偏移才是计算机视角里真正的“位置”。
正解位置索引通常记录的是词位序号——也就是该词是文档分词后的第几个词,而不是字节偏移。词位序号直接服务于“相邻/间隔 N 个词”这种语义判断;字节偏移主要用于结果高亮等展示功能。Lucene 的 term position 就是词位,与字符偏移分开存储,各司其职。
为何常见:一提到“位置”,编程直觉立刻想到字节下标、数组索引,忽略了信息检索里“位置”是为词距语义服务的抽象单位。
误区有人认为位置索引不过是在倒排表里多存一个整数,体积大概翻一倍,不影响大局。
正解位置索引的体积大约与语料库的全部词项出现次数成正比,而普通倒排表只与“文档-词项”对的个数成正比;同一词在一篇文档出现 10 次就要记 10 个位置,膨胀通常是数倍而非一倍。这也是工程上要用差分编码、变长字节、位置截断来控制体积的原因。
为何常见:估算时下意识只算“每篇文档多一个坐标”,忘了每个词每次出现都要记一个位置,而文档里高频词重复出现极多。
误区以为只要给中文做了分词,建好位置索引,中文短语查询就和英文完全一样了,不存在任何差异。
正解分词本身的歧义会沿着流水线传导:查询“金色麦田”分词成“金色/麦田”,但文档“金色的麦田”分词成“金色/的/麦田”,位置差是 2 而非 1,普通短语查询照样匹配不上。中文场景往往需要配合近邻查询、查询改写与词典更新,才能实现灵活匹配。分词质量直接决定位置索引的上限。
为何常见:把“分词”看作一个已经解决的预处理步骤,忽略它引入的边界噪声与未登录词问题,误以为词序列一旦生成就和英文一样干净。
面试题
Q1. 倒排索引的倒排表记录的主要内容是什么?
- A.文档的完整内容
- B.词项所在的文档编号← 正确答案
- C.词项的拼音标注
- D.文档的创建时间
答案:B。倒排表是词项指向文档的映射,记录包含该词项的文档编号。用老周的比喻,每个词条下挂的就是“书号列表”。A 是全文存储,C 和 D 与检索无关。
Q2. 位置索引相比普通倒排索引,额外记录了哪种信息?
- A.文档的大小信息
- B.词项的位置序列← 正确答案
- C.作者的写作时间
- D.文档的语言种类
答案:B。位置索引在“文档编号”之外增加了“词项在文档中出现的位置列表”,相当于老周在书号后补上了页码行号。其余选项与位置索引的定义无关。
Q3. 对两词短语“金色麦田”,下列哪种情况才算短语命中?
- A.两个词都出现即可
- B.后词紧跟在前词后一位← 正确答案
- C.前词位置小于后词
- D.前词紧跟在后词后一位
答案:B。B 对应 pos(麦田) = pos(金色) + 1,顺序与相邻都满足。A 只保证共现;C 只保证顺序不保证相邻;D 顺序反了。
Q4. 有序近邻查询(k=3)要求两词满足什么关系?
- A.两词任意顺序相距不超三
- B.前词在前且距离不超三← 正确答案
- C.两词必须完全相邻
- D.后词必须在前词之前
答案:B。有序近邻要求第二个词在第一个词之后,且位置差不超过 k。A 是无序近邻的定义;C 是短语查询;D 顺序颠倒。
Q5. 位置差分编码中 gi = pi − p(i−1) − 1 的主要目的是什么?
- A.对位置进行加密处理
- B.让位置值变小利于压缩← 正确答案
- C.对文档进行排序处理
- D.提高查询匹配精度
答案:B。差分把大的绝对位置值转成小的间隔值,配合变长字节编码能显著压缩索引体积。它与加密、排序、匹配精度都没有关系。
Q6. 位置索引的总规模大致与什么成正比?
- A.词典中词项的总数量
- B.文档的词项出现总数← 正确答案
- C.索引中的文档总数
- D.不同词语的数量
答案:B。每个词每次出现都要记录一条位置,因此位置总量约等于语料库全部文档的词项出现总数(总词数),远大于词典规模或文档数量。
Q7. 下列哪些是位置索引的空间优化手段?
- A.对位置做变长编码← 正确答案
- B.存储位置差分值← 正确答案
- C.为词保存完整文档
- D.用跳跃指针加速← 正确答案
答案:ABD。变长编码与差分存储缩小整数占用,跳跃指针加速求交、间接降低扫描开销;C 保存完整文档是全文存储,反而更占空间。
Q8. 关于中文分词与位置索引,下列说法正确的是?
- A.中文必须先分词再建索引← 正确答案
- B.查询分词后与文档对齐← 正确答案
- C.中文无法使用位置索引
- D.字级索引会产生大量噪声← 正确答案
答案:ABD。中文没有空格,按词建位置索引必须先分词;查询同样分词后才能与文档词序列对齐匹配。字级索引把词拆成单字,导致大量误召回,所以 D 正确、C 错误。
Q9. 无序近邻查询的距离判定条件是?
- A.后词位置减前词位置为一
- B.两词位置差绝对值不超 k← 正确答案
- C.两词位置差恰等于窗口
- D.两词必须位置完全相同
答案:B。无序近邻不要求先后顺序,因此用绝对值判断距离:|p1 − p2| ≤ k。A 和 C 是特定情形,D 要求同一词位,均不符合。
Q10. 位置索引常用于哪些检索场景?
- A.支持短语查询匹配← 正确答案
- B.支持近邻查询检索← 正确答案
- C.支持中文分词对齐← 正确答案
- D.直接压缩文档正文
答案:ABC。位置索引的核心价值在于短语匹配、近邻检索以及分词后的词序对齐;压缩文档正文属于存储压缩领域,与位置索引无关。