数据库一直在往前发展,从分布式,再到HTAP,向量场景的存储和查询,看着有些老师在AI方面有所建树,甚是羡慕,所以自己也得选择下一个数据库方面的赛道进行学习,hybrid search,混合搜素是我给自己选择的下一个学习的方向。

启发我的是在一个类似于万能的网站(别私信我,问是什么),我发现他们提供的信息可分析的内容非常的丰富,除了文字,声音,图像以及视频都可以混合的进行数据分析,且进行结果的搜索。这里我意识到一个问题,后续的数据库产品必须具备混合搜索的能力,也就是数据多种多样,搜索无所畏惧。

我们要抛弃掉什么二位表格,数据量大,以及数据形式的多种多样的限制,数据库存的是数据而不是规则和限制的时代到来了。那么为什么要混合搜素,首先我们要明确几点,

1 向量搜索不可控

2 关键词搜索会错过语义的问题,比如吃饱了和撑着了明显者是两个词,但意思是一个,所以数据库搜索应该可以接受两个不一样的词但表达同一个意思的方式来查询。

3 图像声音视频等,还在用关键字查询的方式应该被淘汰了

那么什么是hybrid search ,hybrid search = 向量检索 + 关键词过滤,一个混合搜索的场景包含了

1 使用向量模型进行语义理解,对内容进行初步查筛

2 对初步的内容进行关键词,结构化过滤

3  精确查询,且对数据进行融合排序

具体的工作原理可以总结为;

对传入的查询,创建密集向量 (dense vector)(用于语义搜索)和稀疏向量 (sparse vector)。

利用嵌入模型生成密集向量,它是一种高维向量,包含大部分非零值,用于捕获文档的语义含义、关系和属性。

利用分词器 (tokenizers) 创建稀疏向量,它是一种高维向量,包含大部分零值,其中少数非零元素代表文档中的每个独特标记。稀疏搜索通常使用 BM25 算法进行,该算法根据搜索词出现的频率和文档长度来确定相关性。

独立执行两种搜索,获取各自的顶部 K 个结果。

重新排序 (Re-ranking) 结果:将两种搜索的结果合并,并根据某种评分系统(如倒数排名融合 Reciprocal Ranked Fusion, RRF 或使用 Alpha 参数)进行重新排序,以确定最终排名。RRF通过加权评分系统来定义高排名项对最终分数的影响。Alpha 参数则决定了稀疏索引和密集索引的优先级。

在进行分析的过程中,查找了一些开源数据库产品,这里有PostgreSQL, MySQL,MongoDB等,这些开源数据库产品中对于hybrid支持最好的是PostgreSQL,处于中间水平的事MongoDB,而最差的事MySQL.

我们这里简略的说一下

1 PostgreSQL支持hybrid查询,需要加载vector的extension.

CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documents (id serial PRIMARY KEY,content text,content_tsv tsvector GENERATED ALWAYS AS (to_tsvector('english', content)) STORED,embedding vector(384)  -- 假设用 OpenAI 的 ada-002,384维
);
CREATE INDEX ON documents USING GIN(content_tsv);     -- 全文索引
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);  -- 向量近似搜索
-- 向量搜索结果
WITH vector_results AS (SELECT id, 1 / (1 + embedding <#> '[...]'::vector) AS scoreFROM documentsORDER BY embedding <#> '[...]'::vectorLIMIT 10
),
-- 全文搜索结果
text_results AS (SELECT id, ts_rank(content_tsv, plainto_tsquery('postgresql')) AS scoreFROM documentsWHERE content_tsv @@ plainto_tsquery('postgresql')ORDER BY score DESCLIMIT 10
),
-- 合并并重排序
combined AS (SELECT id, score, 'vector' AS source FROM vector_resultsUNION ALLSELECT id, score, 'text' AS source FROM text_results
)
SELECT id, SUM(score) AS hybrid_score
FROM combined
GROUP BY id
ORDER BY hybrid_score DESC
LIMIT 10;

而MongoDB可以通过Atlas search + 向量索引的方式解决,如

{"_id": 1,
"title": "PostgreSQL Hybrid Table",
"content": "Hybrid tables connect PostgreSQL with external systems.",
"embedding": [0.123, 0.234, ..., 0.456]
}{
"$search": {"compound": {"should": [{"text": {"query": "postgresql hybrid","path": "content"}},{"knnBeta": {"vector": [...],"path": "embedding","k": 10}}]}}
}

这里最差的是MySQL,目前只能通过全文索引的方式来进行,且还要借助外部的faiss 等工具来完成hybrid的工作,实属是太麻烦了。

所以后续将聚焦在PostgreSQL或MongoDB等数据库来研究hybrid搜索的方式方法。

卷呀卷,Hybrid 混合查询学习--哪个库是小趴菜_MySQL