
如何读懂Zvec全文倒排索引ANTLR CRoaring构建中文FTS的完整指南【免费下载链接】zvecA lightweight, lightning-fast, in-process vector database项目地址: https://gitcode.com/GitHub_Trending/zve/zvecZveczvec是一款轻量级、进程内的极速向量数据库除了向量检索它还内置了完整的全文检索FTS能力——通过 ANTLR 解析查询语法、CRoaring 位图做倒排求交、jieba 分词处理中文实现了真正可用的中文全文倒排索引。本文将带你从零理解这条写入分词 → 倒排存储 → 查询求交 → BM25 打分的完整链路帮助新手快速建立对 zvec 全文搜索架构的整体认知。一、先搞清楚FTS 在 zvec 里长什么样zvec 的数据库层按列组织索引全文检索由FTS 列独立承担。整个模块集中在 fts_column/ 目录下结构非常清晰子目录职责关键文件gen/ANTLR 生成的词法/语法解析器FtsParser.ccparser/把解析树转成查询 ASTfts_query_parser.htokenizer/分词器与过滤管道jieba_tokenizer.hposting/倒排表的 BitPacking 与 SIMD 解码bitpacked_posting_list.hiterator/Term/Phrase/AND/OR 迭代器求交求并fts_conjunction_iterator.h根目录索引器、BM25 打分、AST 定义bm25_scorer.h存储层方面每个 segment 对应一个独立的 RocksDB 实例fts.rocksdb倒排数据按列族Column Family拆分postings 主表、$POS词项位置支持短语查询、$TF词频、$MAX_TF、$DOC_LEN、$SEGMENT_STAT统计信息用于 BM25见 fts_column_indexer.h 中open()的七条 CF 参数以及上层管理者 fts_indexer.h。二、查询入口ANTLR 如何把查询串变成语法树FTS 支持类似 Elasticsearch 的查询语法布尔运算AND / OR / NOT、必须/排除前缀 / -、短语查询精确短语、字段前缀title:、以及权重 boost^2。这套语法的定义只有两个 ANTLR 文件FtsLexer.g4词法规则。特别注意 FtsLexer.g4 中的UNI_CHAR: [\u0080-\uFFFF]片段——TERM 允许直接以中文字符开头并连续匹配这正是中文查询词能被整体识别为单个 term 的关键FtsParser.g4语法规则用优先级链OR → AND/NOT → 隐式相邻 → 一元修饰 → 原子实现了标准的布尔查询文法其中a NOT b被明确定义为a AND NOT b的简写见 FtsParser.g4 的注释。ANTLR 的 .g4 文件只是文法描述真正的 C 解析器代码由生成脚本 gen_parser.sh 调用 antlr-4.8-complete.jar 产出依赖库放在 thirdparty/antlr/ 中。生成后的解析树随后被 FtsQueryParser 转换为一棵轻量 AST节点类型定义在 fts_query_ast.hTERM / PHRASE / AND / OR / EMPTY。几个设计细节值得注意中文查询与索引使用同一条分词管道。parse()必须传入与建索引一致的TokenizerPipeline保证查询侧分词 文档侧分词避免查不到fts_query_parser.h 的注释强调了这一点默认布尔操作符可配相邻裸词默认按OR组合兼容历史行为也可切到AND对齐 Lucene 的default_operator语义fts_query_parser.h分析器把所有词都滤掉时返回EmptyNode而非空指针与 AND/OR 自然组合调用方无需特判 nullfts_query_ast.h。三、中文支持的核心jieba 分词器中文没有天然空格分词zvec 的做法是把 cppjieba 封装成一个可插拔分词器JiebaTokenizer。几个实用要点默认使用 CutForSearchsearch 模式即对长词做细粒度切分如自然语言处理会同时产出自然语言和语言处理等更细的词索引和查询都采用这一粒度兼顾召回与匹配精度jieba_tokenizer.h 的注释通过 JSON 配置cut_mode可切换search / mix / full / hmm四种模式user_dict_path支持加载用户自定义词典方便加入项目专有词汇分词器只是管道第一环停用词过滤等属于 TokenFilter 职责整条管道由 tokenizer_pipeline_manager.h 统一调度同参数管道全局共享初始化后的分词器支持多线程并发 Cut写入吞吐不受单锁限制。写入路径上FtsIndexer::insert(field, seg_doc_id, text)把文档按字段送入索引器分词后以跨列族WriteBatch一次原子写入 postings、位置、词频、文档长度等多个 CFfts_indexer.h、fts_column_indexer.h 的注释。segment 封存时会把 postings 转为BitPacked格式并丢弃辅助 CFsealfts_indexer.h读取端则用 SIMDAVX2/SSE4.1/标量三档分发见 posting/ 目录下的bitpacked_simd_dispatch批量解压 doc_id 数组。四、CRoaring 位图倒排求交的性能底座查询执行的核心是多个词项的 doc_id 集合做交并差。zvec 的底层集合抽象是基于 CRoaring 的线程安全封装 ConcurrentRoaringBitmap提供两套实现32 位版ConcurrentRoaringBitmap32面向单个 segment 内的 doc_id读操作用shared_lock、写操作用unique_lock还支持range_cardinality快速统计区间内命中文档数64 位版ConcurrentRoaringBitmap64面向全局 doc_id默认以 32 位运行一旦 doc_id 超过 uint32 上限自动升级 64 位upgrade_from_32_to_64()concurrent_roaring_bitmap.h既省内存又不改调用方代码。为什么选 Roaring 位图而不是朴素数组因为位图按高 16 位分容器数组/位图/字节三种编码求交是位运算级操作、压缩率高恰好匹配倒排求交集合密集、范围连续的数据特征。在查询侧位图与迭代器体系配合TermIterator逐 doc_id 推进ConjunctionIteratorAND 求交 与 DisjunctionIteratorOR 求并按 AST 树组装PhraseIterator则利用$POS列验证词项位置相邻以支持中文短语精确匹配。五、BM25 打分结果按相关性排序求交只是找到文档排序靠 BM25。bm25_scorer.h 中的打分器依赖前面各 CF 提供的原料idf来自倒排词项的文档频率tf与文档长度来自$TF、$DOC_LENCF平均文档长度等全局统计来自$SEGMENT_STATCF跨 segment 汇总后得到open_reader会显式接收BM25Params(k1, b)fts_column_indexer.h。最终每个FtsResult携带全局doc_id与 BM25 分数fts_column_indexer.h上层 collection_query 再把 FTS 结果与向量召回、标量过滤做融合实现向量 全文混合检索。六、动手体验跑一个全文检索用例想看真实效果推荐两个入口Python 端到端测试test_collection_fts.py 覆盖建集合、写中文文档、FTS 查询、混合查询全流程同目录还有 test_collection_fts_vector_hybrid.py 演示 FTS 与向量的混合召回C 引擎层测试tests/db/sqlengine/ 下的 fts_recall_test.cc、fts_multi_segment_test.cc 验证多 segment 场景的召回正确性fts_parser_test.cc 则专门验证 ANTLR 解析器对各种布尔查询的边界行为性能基准tools/db/fts_bench_main.cc 提供 FTS 专项压测工具。七、小结一张图看懂 zvec 中文 FTS 架构查询侧ANTLRFtsLexer.g4 FtsParser.g4→ 布尔查询 AST → 分词管道jieba与索引同构→ 迭代器求交/求并Roaring 位图加速存储侧per-segment RocksDB七个列族分工存倒排/位置/词频/文档长度/统计BitPacked SIMD 压缩解码排序侧BM25 打分参数与统计跨 segment 汇总中文友好词法层原生支持 Unicode 连续词、jieba 细粒度切分 用户词典、$POS列保证短语查询位置精确。这套轻量文法 成熟位图库 可插拔分词管道的组合让 zvec 在进程内就能提供接近搜索引擎体验的中文全文检索值得做检索增强RAG、本地知识库的开发者参考 fts_column/ 源码深入阅读。【免费下载链接】zvecA lightweight, lightning-fast, in-process vector database项目地址: https://gitcode.com/GitHub_Trending/zve/zvec创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考