RAG绝配: Postgres推出混合搜索
文中参考文档可点击阅读原文打开, 推荐《最好的PostgreSQL学习镜像》。
RAG绝配: PG开源全文检索+语义(向量)混合搜索插件
背景
LLM RAG非常依赖靠谱的搜索解决方案, 单纯的向量相似(语义)搜索其实召回效果不太行, 《提升RAG召回效果的方法探讨》这篇文章有详细论述. 要达到好的效果, 其实还需要结合全文检索、其他的条件过滤(例如时间ranking等). 而这正是PG擅长的.
原文: https://www.paradedb.com/blog/elasticsearch_vs_postgres
在过去六个月中,我们采访了 50 多家公司,他们正在寻找针对 Postgres 中存储的数据的全文搜索 (FTS) 解决方案。对于其中许多公司而言,决策归结为 Elasticsearch 与原生 Postgres 全文搜索。
通过与这些公司合作,我们确定了每种解决方案的优势领域。以下是我们了解到的情况。
什么是全文搜索 (FTS)?
全文搜索是一种根据特定关键字和短语的存在情况在文本集合中查找条目的技术。大多数搜索引擎(如 Elasticsearch)都使用 BM25 算法对搜索结果进行排名。BM25 会考虑某个术语出现的频率(TF)以及该术语在所有文档中的独特性(IDF)。
全文搜索不同于相似性搜索(也称为向量搜索),后者根据语义搜索并对结果进行排序。许多现代应用程序都结合使用全文搜索和相似性搜索。这种做法称为混合搜索,可以产生更准确的结果。
Postgres 全文搜索
Postgres FTS是所有 Postgres 数据库都具备的一项原生功能。它利用tsvector数据类型(将文本存储为可搜索标记)和 GIN/RUM 索引(可提高搜索速度)。
优点
简单。Postgres FTS 不需要额外的基础设施,并且可在所有托管的 Postgres 服务(如 AWS RDS)上使用。从长远来看,无需协调和管理外部搜索引擎可以节省大量时间和精力。
实时。使用 Postgres FTS,数据提交后即可立即搜索。对搜索体验延迟敏感的业务场景(例如电子商务网站 或 金融科技)非常有用。
支持事务和 MVCC。Postgres的 ACID 事务和多版本并发控制 (MVCC) 确保 FTS 结果在并发访问和频繁更新下的可靠性。
缺点
搜索功能不完整。Postgres FTS 的功能有限,可能会让一些公司望而却步。缺少的功能包括: BM25 排序、相关性调整(自定义IDF?)、自定义分词器(注: 支持自定义词典啊,调查有误?) 和 分面(注: https://blog.csdn.net/sunqp0208/article/details/44938137 )。
大型数据集上的性能较差。虽然 Postgres FTS 在包含几百万行的表上表现良好,但对于包含数千万行的表,性能会大大下降。(注: 需要吞吐大、IOPS高、低延迟的块设备, 例如nvme ssd. 亿级别应该是可以支撑的. )
事务开销。在列上创建 GIN 索引会给影响该列的事务增加少量(通常为几毫秒)的延迟。(注: 开启fastupdate可以避免这个问题, 但是大并发DML场景可能会导致pending list过大影响查询性能. https://www.postgresql.org/docs/current/gin-tips.html / https://www.postgresql.org/docs/current/gin-implementation.html#GIN-FAST-UPDATE )
划重点
Postgres FTS 非常适合搜索不需要复杂 FTS 查询的小型到中型表。我们故意模糊“中型”和“复杂”的含义——具体情况取决于您的性能要求。幸运的是,测试和迁移到/从 Postgres FTS 相当简单。
Elasticsearch
虽然 Elastic 如今提供各种各样的产品,但其核心产品 Elasticsearch 是一个数据存储和全文搜索引擎。
优点
全面的功能集。Elasticsearch 能够处理几乎所有的 FTS 查询。Elastic Query DSL(全文搜索领域特定语言)是全文搜索功能的黄金标准。
性能卓越。我们的基准测试表明,得益于底层久经考验的 Lucene 搜索引擎和分布式架构,Elasticsearch 可以在几毫秒内查询数十亿行数据。
不仅仅是搜索。除了 FTS,Elasticsearch 还是一个分析查询引擎、矢量数据库、安全和可观察性平台。许多组织都喜欢在 Elasticsearch 中整合多项服务的简单性。
缺点
不可靠的数据存储。我们采访过许多尝试过但后悔使用 Elasticsearch 作为主要数据存储的公司。Elasticsearch 缺乏 ACID 事务和 MVCC,这可能导致数据不一致和丢失,而其缺乏关系属性和实时一致性,使许多数据库查询变得具有挑战性。
需要 ETL 管道。由于 Elasticsearch 不是可靠的数据存储,使用 Postgres 的用户通常需要从 Postgres 提取、转换和加载 (ETL) 数据到 Elasticsearch。由于 ETL 管道中的故障可能导致各种中断,因此需要小心维护这些ETL管道,以避免业务查询Elasticsearch的数据有误。
数据新鲜度损失。ETL 作业非常耗时,并且会定期运行(注: 全量, 修复ETL的过错)。到达 Elasticsearch 的数据通常比到达 Postgres 的数据滞后几个小时,这对于在 Postgres 表上执行实时搜索的应用程序来说可能是无法承受的。
昂贵。我们惊讶地听到几家企业表示,Elasticsearch 已成为他们最大的软件支出。随着 Elasticsearch 集群成本的膨胀,许多企业从 Elasticsearch Cloud 转向自建。虽然这减少了他们的云支出,但也带来了一个新问题:Elasticsearch 的运行、调整和管理非常困难。这些组织随后聘请了(昂贵的)工程师来管理他们的 Elasticsearch 集群。
划重点
Elasticsearch 以运营开销和数据新鲜度为代价提供出色的搜索性能。如果其他轻量级替代方案无法完成工作,或者除此以外您还打算使用 Elasticsearch 的其他功能,我们建议您使用 Elasticsearch。
其他搜索引擎
多年来,出现了 Algolia、Meilisearch 和 Typesense 等现代搜索引擎。这些引擎通常用于构建面向用户的搜索体验。例如,Hacker News 搜索就是基于 Algolia 构建的。
虽然每项服务都有各自的特点,但对于希望使用 Postgres 搜索的开发人员来说,有一个重要的警告:这些解决方案都不是专门为 Postgres 构建的。Postgres 用户在使用这些服务时可能会遇到与使用 Elasticsearch 时相同的许多问题。
有可能实现两全其美吗?
ParadeDB 是一款专为 Postgres 构建的全文搜索引擎。ParadeDB 由名为pg_search的扩展提供支持,在 Postgres 中嵌入了基于 Rust 的 Lucene 替代方案 Tantivy。与原生 Postgres FTS 一样,ParadeDB 可插入任何现有的、自我管理的 Postgres 数据库,无需额外的基础设施。与 Elasticsearch 一样,ParadeDB 提供了高级全文搜索引擎的功能。
ParadeDB pg_search 开源项目: https://github.com/paradedb/paradedb/tree/dev/pg_search
ParadeDB可能在RAG应用场景的召回阶段中可以发挥较好的作用? 《提升RAG召回效果的方法探讨》
ParadeDB pg_search 使用举例
假设已安装pg_search和vector插件.
创建测试数据表mock_items, 并生成测试数据
CALL paradedb.create_bm25_test_table(
schema_name => 'public',
table_name => 'mock_items'
);
创建mock_items的索引default_idx
CALL paradedb.create_bm25(
index_name => 'default_idx',
table_name => 'mock_items',
key_field => 'id', -- 基表的PK字段, 必须指定
text_fields => paradedb.field('description') || paradedb.field('category'),
numeric_fields => paradedb.field('rating')
);
调用索引的search函数进行全文检索(应该是封装成schema,function方便调用, 正常情况PG SQL没有这种用法.)
SELECT description, rating, category
FROM default_idx.search(
'(description:keyboard OR category:electronics) AND rating:>2',
limit_rows => 5
);
mock_items表新增向量字段, 正常情况是需要将相关文本转换为向量(有个转换过程), 例子中偷懒直接生成了一个模拟向量.
ALTER TABLE mock_items ADD COLUMN embedding vector(3); UPDATE mock_items m
SET embedding = ('[' ||
((m.id + 1) % 10 + 1)::integer || ',' ||
((m.id + 2) % 10 + 1)::integer || ',' ||
((m.id + 3) % 10 + 1)::integer || ']')::vector;
创建向量索引
CREATE INDEX on mock_items
USING hnsw (embedding vector_l2_ops);
查询mock_items表, 根据向量相似进行排序
SELECT description, category, rating, embedding
FROM mock_items
ORDER BY embedding <-> '[1,2,3]'
LIMIT 3;
调用索引的search函数, 全文检索+向量搜索混合检索
SELECT * FROM default_idx.score_hybrid(
bm25_query => 'description:keyboard OR category:electronics',
similarity_query => '''[1,2,3]'' <-> embedding',
bm25_weight => 0.9,
similarity_weight => 0.1
) LIMIT 5;
将结果使用PK进行关联查询, 可以获取基表中的其他字段内容.
SELECT m.description, m.category, m.embedding, s.score_hybrid
FROM mock_items m
LEFT JOIN (
SELECT * FROM default_idx.score_hybrid(
bm25_query => 'description:keyboard OR category:electronics',
similarity_query => '''[1,2,3]'' <-> embedding',
bm25_weight => 0.9,
similarity_weight => 0.1
)
) s
ON m.id = s.id
LIMIT 5;
参考
插件:
paradedb pg_search: https://github.com/paradedb/paradedb/tree/dev/pg_search rum: https://github.com/postgrespro/rum vector: https://github.com/pgvector/pgvector zombodb: https://github.com/zombodb/zombodb
索引接口:
gin rum hnsw ivfflat zombodb
其他:
https://www.paradedb.com/blog/elasticsearch_vs_postgres https://github.com/paradedb/paradedb/tree/dev/pg_search https://docs.paradedb.com/api-reference/full-text/filtering https://docs.paradedb.com/welcome/quickstart 《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 1 文本(关键词)分析理论基础 - TF(Term Frequency 词频)/IDF(Inverse Document Frequency 逆向文本频率)》 《PostgreSQL+pg_bestmatch+pgvector 打造适合自己文档库的TF-IDF加权, 库内将文本转换为向量, 提升文本搜索精确度和性能》 《使用 PolarDB 开源版 smlar 插件进行高效率相似文本搜索、自助选药、相似人群圈选等业务》 《PostgreSQL 在资源搜索中的设计 - pase, smlar, pg_trgm - 标签+权重相似排序 - 标签的命中率排序》 《社交、电商、游戏等 推荐系统 (相似推荐) - 阿里云pase smlar索引方案对比》 《PostgreSQL 相似搜索插件介绍大汇总 (cube,rum,pg_trgm,smlar,imgsmlr,pg_similarity) (rum,gin,gist)》 《海量数据,海明(simhash)距离高效检索(smlar) - 阿里云RDS PosgreSQL最佳实践 - bit string 比特字符串 相似度搜索》 《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 3 rum, smlar应用场景分析》 《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 2 smlar插件详解》
本期彩蛋 - 数据库生态工具&信创开源数据库
用好周边工具, 数据库管理水平战胜90%老司机
1、管控软件
云猿生开源的kubeblocks, 如果你要管理很多套并且种类很多的数据库产品, 推荐选择.
https://github.com/apecloud/kubeblocks
乘数开源的clup, 专门用来管理PostgreSQL和PolarDB的集群管理软件, 如果你要管理很多套数据库, 推荐选择. 并且clup还提供了企业版、自研的连接池、分布式存储、一体机、备份平台等, 企业可以关注一下.
https://www.csudata.com/
若航开源的pigsty, 集成了300多个PG插件的PG集群和PolarDB集群管理软件, 如果你要管理很多套数据库, 并且对插件有特别多的需求, 推荐选择.
https://pigsty.cc/zh/
2、审计监控诊断优化
海信聚好看的 DBdoctor, 采用ebpf技术, 在对数据库几乎没有影响的情况下实时监控数据库和服务器的各项指标, 发现和诊断问题根因非常方便.
https://www.dbdoctor.cn/
Bytebase 的目标非常远大, 是位于您和数据库之间的中间件。它是数据库 DevOps 的 GitLab/GitHub,专为开发人员、DBA 和平台工程师打造。
https://bytebase.cc/docs/introduction/what-is-bytebase/
D-Smart, Oracle老前辈白老大他们搞的, 专注企业级市场, 将业界顶级DBA经验的产品化作品, 产品功能包括数据库监控、诊断、优化等.
https://www.modb.pro/db/567140
3、数据同步&迁移&备份恢复
NineData, 老领导出去创业做的产品, 产品涵盖了数据同步、迁移、备份、比对、devops、chatDBA等.
https://www.ninedata.cloud/home
DSG, 非常老牌的数据库同步迁移企业级产品, 支持各种数据库的异构和同构迁移, 用他们的话说, 没有dsg搞不定的迁移, 比goldengate还牛.
https://www.dsgdata.com/
通过信创并且开源的数据库:
PolarDB for PostgreSQL
https://github.com/ApsaraDB/PolarDB-for-PostgreSQL
以下PG系国产数据库也非常值得关注: HaloDB(基于PG兼容PostgreSQL、Oracle、MySQL. http://www.halodbtech.com/ )、IvorySQL(基于开源PG兼容PG、Oracle. https://www.ivorysql.org/zh-cn/ )、ProtonBase(云原生分布式数仓. https://protonbase.com/ ).
参考文档点击阅读原文获得
感谢关注我的github (https://github.com/digoal/blog) 及视频号:
彩蛋2: 全国大学生数据库创新设计赛 点击报名