news 2026/5/1 20:22:25

DuckDB 全文搜索功能解析:虽有局限但实用,还可导出至其他数据库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DuckDB 全文搜索功能解析:虽有局限但实用,还可导出至其他数据库

发布时间:2026 年 4 月 29 日

这是关于 DuckDB 的第一篇文章 [《浅尝 DuckDB》](https://peterdohertys.website/blog-posts/dab-of-duck.html) 的续篇。若对 DuckDB 不熟悉,建议先读那篇文章。DuckDB 让数据源快速且易于被发现的基本工作流程强大却有局限,如搜索历史出版物内容或大量电子邮件,基本文本查询受限。作者对探索 DuckDB 更强大功能感兴趣,本文重点介绍全文搜索(FTS)。作者在使用其他 FTS 解决方案(如 Elasticsearch 和 Postgres 及相关扩展)方面经验丰富,将带读者了解 DuckDB 中 FTS 的现状。

简易 FTS 入门

完整的 FTS 教程超出本文范围,想了解更多可阅读 [Postgres 文档](https://www.postgresql.org/docs/current/textsearch.html)。与使用 `=`、`ilike` 或正则表达式等 SQL 运算符相比,FTS 可进行更全面、可配置的查询,查询得分可用 DuckDB 提供的 [Okapi BM25](https://en.wikipedia.org/wiki/Okapi_BM25) 算法调整。索引选项包括词干提取(将单词还原为共同词根,处理部分词形变化,但对非常规形式有不足)、停用词(去除常见“停用词”,避免影响搜索结果)、去除重音(将 “á”、“ä” 和 “a” 等字符标准化)。查询函数中,Okapi BM25 参数有 k₁(词频,即出现更多实例是否有意义)和 b(长度归一化,即较长文档是否更有意义)。这些功能在 DuckDB 的 FTS 扩展中都有,但只是 FTS 功能的一部分。作者认为 DuckDB 的功能集是个好开端,未来可能添加新功能或发布新扩展,猜测短语查询、向量查询功能以及对可插拔同义词词典的支持可能是开发者考虑的特性。在实验中,DuckDB 无法突出显示查询词在源数据中的匹配位置,Postgres 有 `ts_headline` 解决此问题,作者只能通过 tmux 或 grep 搜索,感到沮丧。写文章时,作者了解到 [Snowball 项目](https://snowballstem.org/),它是创建信息检索词干提取算法的小型字符串处理语言,包含一系列词干提取算法,是大多数数据库和客户端库中词干提取的基础。[Python 的 snowballstemmer 库](https://pypi.org/project/snowballstemmer/) 可用于调试词干提取问题。

环境搭建

全文搜索不是 DuckDB 开箱即用的功能,可通过 [全文搜索扩展](https://duckdb.org/docs/current/core_extensions/full_text_search) 实现。假设已安装 DuckDB,安装 FTS 扩展只需开启新会话并运行命令:

INSTALL fts;LOAD fts;

深入探究

假设拥有几 GB 的电子邮件库,想搜索邮件内容了解政治家、商界领袖和名人的交流话题。作者的数据集中有 13010 封扩展名为 .eml 的电子邮件,包含多种 MIME 类型,DuckDB 无法直接导入,需进行预处理。可在 archive.org、ddosecrets.org 甚至 justice.gov 上找到类似电子邮件集,读者可自行探索,若想跟着操作,任何 .eml 文件集均可。

文件预处理

作者用 Python 和 [uv](https://docs.astral.sh/uv/) 处理原始文件。预处理流程简单直接,丢弃无法清晰解析的电子邮件,包括加载文件、解析正文内容、解析邮件头和元数据以识别营销和交易类邮件,解析成功则将 JSON 数据保存到文件中。

常规操作

1. **导入 JSON 数据并填充数据库**:

CREATE TABLE emails AS SELECT * FROM read_json('*.eml.json');
作者喜欢 DuckDB 显示导入进度和内存使用情况。2. **创建并填充 ID 列**:可在导入数据或预处理循环中完成,作者当时忘记,记录此步骤。
ALTER TABLE emails ADD COLUMN id INTEGER;UPDATE emails SET id = rowid;
3. **创建 FTS 索引**:可对一个或多个列索引,用可选参数控制词干提取器、停用词等,具体参考 [文档](https://duckdb.org/docs/current/core_extensions/full_text_search#pragma-create_fts_index)。
PRAGMA create_fts_index('emails', 'id', 'subject', 'body');
4. **开始查询**:可用各种参数细化或扩大查询范围,参考 [文档](https://duckdb.org/docs/current/core_extensions/full_text_search#match_bm25-function)。介绍了使用默认参数、`conjunctive` 参数、Okapi 的 `k₁` 和 `b` 参数的查询示例。使用较低的 `k₁` 值时,评分策略是 “这个词是否出现过”;使用较高的 `k₁` 值时,重复出现的实例影响排名。
清理操作

可用以下命令删除索引:

PRAGMA drop_fts_index('emails');

总结

DuckDB 的 FTS 功能集不如 Postgres 或 Elasticsearch 完善,但强大且适用于大多数探索性用例。若需更复杂解决方案,可轻松导出 DuckDB 数据并导入到 Postgres 或 Elasticsearch 中。DuckDB 能快速轻松搜索(几乎)任何数据源,作者在实际工作中会优先考虑。作者想继续 DuckDB 系列文章,下一篇可能探讨向量搜索现状。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 20:19:59

3分钟快速掌握微信聊天记录解密:WechatDecrypt工具终极指南

3分钟快速掌握微信聊天记录解密:WechatDecrypt工具终极指南 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 你是否曾经因为误删了重要的微信聊天记录而感到焦虑?或者需要找回某次关…

作者头像 李华
网站建设 2026/5/1 20:17:22

[新产品]医用门简介

${part1}在现代医疗卫生行业,医用门的选择直接关系到医疗机构的整体卫生水平和安全性。传统的门在医疗环境中往往无法满足严格的卫生要求和多样的功能需求,而我们的新产品——医贝尔医用门,则以其卓越的性能和人性化设计,为医疗机…

作者头像 李华