Zvec全文检索(FTS)完全指南:BM25、jieba中文分词与N-gram分词器
2026/9/8 12:33:15 网站建设 项目流程

Zvec全文检索(FTS)完全指南:BM25、jieba中文分词与N-gram分词器

【免费下载链接】zvecA lightweight, lightning-fast, in-process vector database项目地址: https://gitcode.com/GitHub_Trending/zve/zvec

Zvec 是一款轻量、极速的进程内向量数据库,除了向量相似度检索,它还内置了原生的**全文检索(Full-Text Search, FTS)**能力:基于BM25算法的相关性打分、jieba 中文分词N-gram 分词器以及一套 Lucene 风格的查询语法,让"关键词精确搜索"和"语义向量搜索"能在同一个引擎里共存、混合查询。这篇指南将带你从零理解 Zvec 全文检索的每个核心部件,新手也能快速上手。

一、什么是 Zvec 全文检索(FTS)?

传统向量检索擅长"意思相近"的召回,但面对精确关键词(型号、订单号、报错代码、人名等)往往力不从心。Zvec 的 FTS 正是为此设计:

  • 关键词检索:支持自然语言或结构化表达式搜索字符串字段;
  • BM25 相关性排序:命中的文档按经典 IR(信息检索)打分排序,而不仅是"命中/未命中";
  • 多分词器可插拔standard(默认)、jieba(中文)、ngram(短文本/代码/短语)、whitespace四种内置分词器;
  • 与向量检索混合:同一次查询中可以融合 FTS、向量语义与标量过滤。

核心实现集中在src/db/index/column/fts_column/目录,按职责清晰分层:

fts_column/ ├── bm25_scorer.h / .cc # BM25 打分与 WAND 优化 ├── tokenizer/ # 分词器与过滤器 │ ├── jieba_tokenizer.h # 中文分词 │ ├── ngram_tokenizer.h # N-gram 分词 │ ├── standard_tokenizer.h # 标准分词 │ └── tokenizer_factory.cc # 分词器工厂 ├── iterator/ # 倒排迭代器(AND/OR/短语) └── posting/ # 位压缩倒排表 + SIMD 加速

二、BM25 相关性打分:结果为什么这样排序?

BM25(Best Matching 25)是信息检索领域的经典打分函数,Zvec 在 bm25_scorer.h 中完整实现了标准公式:

核心思想:一个词在某篇文档里出现得越多(词频 tf),且在整个语料中越罕见(逆文档频率 IDF),这篇文档的相关性就越高;同时用文档长度归一化避免长文档"占便宜"。

Zvec 的关键工程细节:

设计点说明
经典默认参数k1 = 1.2(词频饱和)、b = 0.75(长度归一化),符合 IR 通用最佳实践
分段统计BM25 统计量(文档总数、总词数、平均文档长度)按 segment 独立维护,读写线程安全
WAND 剪枝用词的最大词频预计算分数上界,TopK 检索时提前跳过不可能进入前列的文档,显著减少无效打分
增量统计写入时实时更新统计量,保证搜索立刻使用最新语料状态

💡新手理解:你不需要手动调参——默认参数已经过基准调优,绝大多数场景开箱即用。

三、分词器怎么选?jieba、N-gram 与 standard

分词器决定了"什么算一个词",直接决定检索质量。Zvec 在 tokenizer_factory.cc 中提供四种分词器:

1️⃣standard(默认)——通用英文/混合文本

按 Unicode 边界切分单词,适合英文为主的场景。可以叠加 token 过滤器(在FtsIndexParamfilters中配置):

  • lowercase:统一小写;
  • ascii_folding:去掉重音字符(café → cafe);
  • stemmer:基于 Snowball 的词干还原(running → run)。

2️⃣jieba—— 中文分词的可靠选择

中文没有天然空格分词,standard分词器会把整句当一个词。jieba 分词器(jieba_tokenizer.h)内置了 cppjieba 引擎:

  • 默认使用CutForSearch(搜索引擎模式),产出更细粒度的词——既切出"中华人民共和国",也切出"中华""人民",保证索引与查询两侧都能命中;
  • 四种切分模式可配:search(默认)、mixfullhmm
  • 支持用户自定义词典user_dict_path)注入领域术语,支持指定词典目录(jieba_dict_dir);
  • 初始化后线程安全,可并发调用 tokenize。
"全文检索" --jieba--> [ 全文, 检索, 全文检索 ]

3️⃣ngram—— 短语、代码与短文本的利器

N-gram 分词器(ngram_tokenizer.h)把文本切成连续字符的 n 元组(默认 2-gram),是 Zvec v0.7.0 新增的能力,特别适合:

  • 短语与子串匹配:"vector" 能匹配 "vectorize"、"vector_db";
  • 代码检索:函数名、路径等没有空格边界的标识符;
  • 短文本:标题、标签、命令。

配置项:ngram_min/ngram_max(默认均为 2,差值不超过 1)、token_chars(可选限定参与切分的字符类别,如letterdigit)。

4️⃣whitespace—— 按空格切分

最简单直接:以空白为界,不改变词形。适合内容本身已有明确分隔符的场景。

选型口诀🧭

中文文档 →jieba;英文/通用 →standard(+filters);代码/短语/子串匹配 →ngram;日志、键值类 →whitespace

四、快速上手:定义 FTS 索引与发起查询

第 1 步:为字段声明 FTS 索引

在 Python SDK 中,给字段挂上FtsIndexParam即可(类型定义见python/zvec/model/param/):

from zvec.model.schema import FieldSchema from zvec.model.param import FtsIndexParam # 中文字段用 jieba 分词 content = FieldSchema( name="content", data_type=zvec.DataType.STRING, index_param=FtsIndexParam(tokenizer_name="jieba"), ) # 代码/短文本字段用 ngram,extra_params 传 JSON 配置 code = FieldSchema( name="code", data_type=zvec.DataType.STRING, index_param=FtsIndexParam( tokenizer_name="ngram", extra_params='{"ngram_min": 2, "ngram_max": 3}', ), )

字段 Schema 的类型定义在 field_schema.py。

第 2 步:用 FTS 查询

查询参数Fts支持两种互斥输入(定义见 query.py):

match_string(宽松匹配)——分词后"任一词命中即返回",适合普通搜索框:

from zvec.model.param import Fts, Query query = Query(field_name="content", fts=Fts(match_string="向量数据库 性能")) results = collection.query(query, topk=10)

query_string(结构化表达式)——Lucene 风格,支持完整布尔逻辑:

语法含义示例
+词必须包含+BM25 +分词
-词必须排除+python -爬虫
"短语"精确短语(保持词序相邻)"全文检索"
and / or / not显式布尔组合召回 and not 排序
query = Query( field_name="content", fts=Fts(query_string='+向量 -向量库 "BM25 分词"'), )

查询表达式由内置解析器编译(语法文件见src/db/index/column/fts_column/FtsLexer.g4FtsParser.g4),支持 AND、OR 与短语迭代的执行计划,性能远优于应用层字符串过滤。

五、Zvec FTS 的性能黑科技(新手也值得知道)

  • 位压缩倒排表:posting list 采用 bit-packing 压缩存储,并提供 SSE4.1 / AVX2 SIMD 加速实现(fts_column/posting/),内存与 CPU 双友好;
  • WAND 剪枝:如前所述,TopK 检索只计算"有希望"的文档分数;
  • RocksDB 承载:倒排索引落在 RocksDB 之上(fts_rocksdb_reducer.cc),多 segment 合并时统计量正确重算,保证 BM25 打分在数据合并后依然准确;
  • 进程内零部署:所有检索发生在你的进程里,没有网络往返,延迟毫秒级。

对应的质量保障也值得放心:单元测试覆盖倒排表、索引器、多 segment 召回(tests/db/sqlengine/fts_recall_test.cc)以及 Python 层的查询校验(python/tests/test_fts_query.py)。

六、混合检索:让 FTS 与向量各展所长

Zvec 的核心卖点是混合检索——FTS 负责"精确词命中",向量负责"语义相似",两者可同场协作:

  • 单次查询融合:FTS 召回 + 向量召回 + 标量过滤在查询计划层融合排序;
  • 稀疏向量路线:SDK 提供 BM25EmbeddingFunction,把文本编码为 BM25 稀疏向量,与稠密向量做加权混合检索;
  • 重排(Rerank):粗召回后接 reranker 精排(src/db/reranker/reranker.cc),进一步提升头部结果质量。

实践建议

  1. 关键词强约束(型号、ID、报错文本)→ 字段挂 FTS 索引,用query_string精确控制;
  2. 语义泛化问题("怎么提升检索效果")→ 向量索引;
  3. 两者都重要 → 混合查询,让引擎替你融合。

七、核心路径速查表 📌

模块路径
BM25 打分器src/db/index/column/fts_column/bm25_scorer.h
jieba 中文分词src/db/index/column/fts_column/tokenizer/jieba_tokenizer.h
N-gram 分词器src/db/index/column/fts_column/tokenizer/ngram_tokenizer.h
分词器工厂src/db/index/column/fts_column/tokenizer/tokenizer_factory.cc
FTS 查询语法src/db/index/column/fts_column/FtsParser.g4
Python 索引参数python/zvec/model/param/
Python FTS 查询python/zvec/model/param/query.py
BM25 稀疏嵌入python/zvec/extension/bm25_embedding_function.py

八、总结

  • Zvec 的 FTS 把BM25 相关性打分可插拔分词器布尔查询语法装进了一个进程内数据库,无需独立搜索引擎;
  • 中文场景首选jieba 分词(搜索引擎切分模式 + 用户词典),代码/短语场景选N-gram,英文场景用standard + 过滤器
  • match_string做宽松召回,query_string做精确控制,再与向量检索混合,即可获得又准又全的搜索体验。

现在,打开 Python SDK,给你的下一个文本字段挂上FtsIndexParam吧——全文检索,一分钟就位 ✅

【免费下载链接】zvecA lightweight, lightning-fast, in-process vector database项目地址: https://gitcode.com/GitHub_Trending/zve/zvec

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询