跳至内容
15 见微知著:全文、模糊与向量检索

第 15 章 见微知著:全文、模糊与向量检索

搜索不是“给某一列加个索引”。它至少包含四个问题:

哪些对象有资格出现?        filtering
从多少对象中找候选?        candidate generation
候选之间怎样比较先后?      ranking
怎样证明结果真的更好?      evaluation

全文检索、三元组模糊匹配和向量近邻解决的是不同子问题:

方法最擅长捕捉主要盲区
PostgreSQL FTS词形归一、多词布尔/短语、字段权重拼写错误、词表之外的语义表达
pg_trgm字符串局部相似、错拼、包含与相似候选业务语义、长文档相关性
向量检索由模型编码的相似性精确词优势、模型偏差、近似召回
混合检索多路召回互补参数、成本、解释与验证复杂度

它们可以组合,却不能因为“混合”两个字就自动更好。本章把检索从演示查询 变成一个可反驳的工程实验:

冻结语料、查询、相关性标注和模型身份;每一路独立产生候选;质量黄金值 使用精确计算;近似索引另测召回;最后才讨论延迟、部署与上线。

本章完成后

你应当能够:

  • 区分精确过滤、词法相关、字符串相似与模型相似;
  • 把查询解析、过滤、候选生成、排序、融合和重排拆成独立阶段;
  • 为检索实验建立带版本的语料、查询集与分级相关性标注;
  • 解释 parser、dictionary、configuration、tsvectortsquery
  • 显式固定文本搜索配置,构造带 A/B 权重的存储生成列;
  • 正确选择 websearch_to_tsqueryplainto_tsqueryphraseto_tsqueryto_tsquery,而不把原始用户输入直接交给严格语法;
  • ts_rank_cd 排序,并知道 0–1 归一化不等于跨检索器可比概率;
  • 解释 similarityword_similarity% 门槛与 GIN/GiST 的边界;
  • 选择 L2、余弦或内积时,把模型训练与归一化合同写清楚;
  • 区分精确近邻与 HNSW/IVFFlat 近似近邻,不用 ANN 结果定义质量黄金值;
  • 解释过滤为何可能降低 ANN 返回数,以及 iterative scan 能补什么、不能 保证什么;
  • 用 RRF 合并不同分数尺度的排名,并知道何时需要校准或重排;
  • 计算 Precision@K、Recall@K、MRR@K 与 NDCG@K;
  • 在 Pigsty 中把扩展装包、数据库启用、版本核对和节点一致性分开验收;
  • 把模型费用、数据出境、向量回填、索引维护、WAL 与副本延迟纳入 ADR;
  • 交付一个可运行、可审校、可精确复位的检索 PoC。

一条有意不完美的实验

贯穿实验位于 shop_ch15,固定:

17 products (16 active + 1 inactive guard)
8 queries
24 graded relevance judgments
4-dimensional handcrafted vectors
3 candidate generators
RRF k=60, source depth=4, result depth=3

四维向量的模型标识为:

pg36-handcrafted-topic-4d-v1

它不是 embedding 模型,也没有调用任何外部 API。它只是可人工核算、每次 重建完全相同的主题坐标,用来隔离数据库机制与模型随机性。真实模型质量必须 用真实文本重新测,不能继承本章数字。

固定评估集得到:

策略Precision@3Recall@3MRR@3mean NDCG@3min NDCG@3
全文0.2916670.2916670.7500000.6130430.000000
模糊0.9166670.9166671.0000000.9428810.842828
精确向量1.0000001.0000001.0000000.8173140.631039
RRF 混合1.0000001.0000001.0000000.9629290.759192

结果故意保留三个反例:

  1. wireles hedphonespostgre databse tuning 的全文结果为空,说明 词形归一不是拼写纠正;
  2. 精确向量覆盖全部相关对象,但次序不总正确,Recall 高不等于 NDCG 高;
  3. q02 上混合 NDCG 为 0.759192,低于纯模糊的 0.842828,说明 融合可以把弱信号带进来。

因此本章的结论不是“向量最好”或“混合必胜”,而是:

the measured winner on this frozen set
is a release candidate for this frozen set

精确质量与近似服务路径分开

质量视图枚举过滤后的全部候选并计算精确 L2 距离,不经过 HNSW。HNSW 只在 独立 probe 中运行:

query = q06 / trail hydration
exact top-3 = 7,8,9
HNSW top-3  = 7,8,9
recall@3    = 1.000000

这一个点证明“能够查询并比较”,不证明生产召回为 1。pgvector 官方说明, 默认无 ANN 索引时是精确搜索;HNSW/IVFFlat 以部分召回换取速度,生产应持续 拿近似结果与精确结果对照。参见 pgvector 0.8.4 README

强制执行计划分别验证:

FTS      -> GIN bitmap index scan
trigram  -> GIN bitmap index scan
exact    -> sequential scan + sort
HNSW     -> HNSW index scan
filtered -> HNSW index scan + active/category filter

这里关闭部分 planner 路径,只为证明索引可用;不是 17 行数据上的性能比较。

实验资产

规范与决策:

输入与实现:

三份 CSV 不只是仓库附件。自动化会从数据库重新导出并执行逐字节比较, fixture-manifest.json 还固定各文件 SHA-256、行数、模型身份、生成方法与 许可证边界。

快速运行

本章复用第 14 章已经安装和认证的扩展,不自行接管扩展生命周期:

export PGSERVICEFILE=/path/to/pg_service.conf
export PGSERVICE=pg36-admin

PG36_EVIDENCE_DIR="$PWD/evidence/ch15" \
  ./static/labs/ch15/task.sh all

all 会:

  1. 验证目标数据库、角色、ch04-v1 模型和第 14 章扩展身份;
  2. 以 owner/marker/对象白名单保护 shop_ch15
  3. 创建带权重的存储 tsvector、四张表、七个排名/质量视图;
  4. 创建全文 GIN、标题 trigram GIN、向量 HNSW 与过滤 B-tree;
  5. 从数据库导出三份 CSV 并与冻结输入逐字节比较;
  6. 采集文档、索引、体积、权限、查询解析、排名和质量证据;
  7. 采集精确计划与三类索引计划;
  8. 以精确集合为真值测一次 HNSW Recall@3;
  9. 证明 pg36_app 可读、更新返回 SQLSTATE 42501
  10. 运行关系、生成列、过滤、质量、checksum 和权限的全量断言;
  11. 证明错误 token、错误 target、活跃 worker 时 reset 分别被拒绝;
  12. 不用 CASCADE 精确复位,确认第 14 章扩展保留,再完整重建复验。

正式 Homebrew PostgreSQL 18.4 证据两轮均得到:

status=ok
fixture=frozen-byte-identical
quality=precision+recall+mrr+ndcg
ranking=fts+trigram+exact-vector+rrf
ann=q06-exact-vs-hnsw-recall-1.000000
guards=P3660+P3661+P3663
extensions=ch14-preserved
pigsty_l1=not-run
release_candidate_checksum=bf92a6ad0f60dc3e125b39dbf67bf4d6c5e50275192bd01a7ca4c50d142f822e

安全边界

task.sh all 会删除并重建带本章精确 marker 的 shop_ch15,只适合 本书本地/开发夹具。它不会删除扩展。生产上应以在线建索引、双写/回填、 灰度读流量和可回退发布替代“删后重建”。

学习路径

15.1 先定义检索任务与评估集

先固定“什么叫好”。没有评估集,后面的任何好看查询都只是故事。

15.2 PostgreSQL 全文检索

从 PostgreSQL 原生词法管线开始,理解它为何强,也理解错拼为何仍会漏。

15.3 模糊匹配与拼写容错

用字符三元组补足错拼,但不给零分 Top-K 贴上“相关”标签。

15.4 可复现的向量检索

把向量看作有来源、有版本、有度量合同的数据,而不是神秘的“AI 列”。

15.5 混合检索与排序验证

学会合并名次、计算指标、解释反例,而不是拿一个查询挑选截图。

15.6 扩展部署与运行代价

把 PostgreSQL 对象映射到 Pigsty 交付和长期运行,不把安装成功当作上线。

15.7 实战:pg36_shop 商品混合检索 PoC

最后运行双周期实验,拿出可以评审、可以拒绝、也可以退出的 proposal。

版本与证据边界

本章原理覆盖 PostgreSQL 14–18;可执行 baseline 固定 pg_trgm 1.6、 vector 0.8.4,并在 PostgreSQL 18.4 上验证。实验使用英语配置,因为冻结 语料是英语。中文、多语言与混合字段不能照抄 english,应重新选择 tokenizer/ dictionary、语料和指标。

Pigsty 映射按 4.4 文档在 2026-07-29 核验。本地证据路径是直接 PostgreSQL, 没有冒充 Pigsty L1。当前 Pigsty 文档把 pgvector 列为默认安装包,把 pg_trgm 列为默认启用扩展;实际环境仍要检查目标版本、镜像/仓库和每个 主备节点。

权威入口:


上一章:博采众长:内核分支与扩展生态 · 返回上卷导读 · 下一章:经天纬地:时序、空间与时空查询 · 查看全书目录 · 查看索引中心

最后更新于