索引构建与维护
在 PostgreSQL 中创建、配置、维护和检查 bm25 索引。
vchord_bm25 提供了 bm25 索引访问方法(CREATE ACCESS METHOD bm25 TYPE INDEX HANDLER _bm25_amhandler)以及 bm25_ops 操作符类。
创建 bm25 索引
稳定发布版(v0.1 – v0.3,bm25vector)
新一代 main 分支(tsvector)
在 main 分支中,bm25_ops 直接作用于 tsvector,并支持索引级存储参数(options、limit 和 prefilter):
存储参数 (WITH (...)) |
类型 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|
options (k1) |
float(TOML 内) |
1.2 |
1.2 – 2.0 |
词频饱和度参数 。数值越大,文档内重复出现的词项权重越高。 |
options (b) |
float(TOML 内) |
0.75 |
0.0 – 1.0 |
文档长度归一化参数 。0.0 禁用长度归一化;1.0 完全按相对于 的文档长度进行归一化。 |
limit |
int |
0 |
0 – 65535 |
存储在索引上的默认 Top-K 检索上限(当会话 GUC bm25.limit = 0 时使用)。 |
prefilter |
bool |
false |
true / false |
存储在索引上的默认预过滤行为(可在会话级通过 bm25.prefilter 覆盖)。 |
你可以使用 ALTER INDEX 动态更新现有索引上的 limit 或 prefilter 参数:
自动分词触发器(v0.1 – v0.3)
使用 pg_tokenizer 时,可以通过触发器在执行 INSERT 和 UPDATE 时自动同步更新 bm25vector 列:
使用自定义模型触发器(一步到位辅助函数)
create_custom_model_tokenizer_and_trigger 会一步完成自定义模型创建、分词器创建、存量数据回填,并自动挂载 BEFORE INSERT OR UPDATE 触发器:
将标准 PL/pgSQL 触发器用于预训练模型
如果你使用的是预训练模型(如 llmlingua2 或 bert_base_uncased),可以创建一个标准的触发器函数:
段架构:增长段(Growing)与封闭段(Sealed)(v0.1 – v0.3)
在内部实现中,vchord_bm25 将索引元组组织为两种段状态:
- 增长段(Growing Segment):新写入的元组(
INSERT/UPDATE)会追加到增长段中,从而无需重新压缩整条倒排链表即可获得极高的写入吞吐量。 - 封闭段(Sealed Segment):当增长段超过
bm25_catalog.segment_growing_max_page_size个页面(默认4096页,约 32 MB)时,它会被封存为不可变的只读段,采用差分位打包(Delta-Bitpacked)的 128 文档块结构,并预计算块级最大得分上界与词项文档频率(DF)统计信息。
并行索引构建与进度监控
索引构建支持 PostgreSQL 并行维护工作进程(Parallel Maintenance Workers),并可通过 pg_stat_progress_create_index 跨三个阶段实时汇报构建进度:
initializing(初始化)scanning table(扫描表)writing index structures(写入索引结构)
检查索引页(v0.3.0)
0.3.0 版本提供了 bm25_page_inspect(index regclass, blkno int) 函数,用于检查 bm25 索引的内部元数据与页头信息:
索引约束与限制
- 仅支持单列索引:
bm25索引只能创建在单个bm25vector(或tsvector)列上,不支持多列联合bm25索引。 - 不支持 Unlogged 表:
bm25访问方法不支持UNLOGGED表(调用ambuildempty会抛出Unlogged indexes are not supported错误)。 - 仅支持正向扫描:
bm25索引扫描在<&>操作符上仅支持正向(ASC)扫描方向。