混合检索

更新时间:2025-04-28 05:56:03

PolarDB PostgreSQL支持多种检索方式,包括密集检索、稀疏检索和混合检索。

背景

  • 密集检索:利用语义上下文来理解查询背后的含义。

  • 稀疏检索:强调文本匹配,根据特定术语查找结果,相当于全文检索。

  • 混合检索:结合密集检索和稀疏检索,捕捉完整的上下文和特定的关键词,从而获得全面的搜索结果。

最佳实践

基础数据准备

  1. 使用高权限账号创建检索所需插件。

    CREATE EXTENSION IF NOT EXISTS pg_jieba;
    CREATE EXTENSION IF NOT EXISTS rum;
    CREATE EXTENSION IF NOT EXISTS vector;
    CREATE EXTENSION IF NOT EXISTS polar_ai;

    其中,各插件功能如下:

  2. 创建表并插入测试数据。

    CREATE TABLE t_chunk(id serial, chunk text, embedding vector(1536), v tsvector);
    
    INSERT INTO t_chunk(chunk) VALUES('大模型产品解决方案文档与社区权益中心定价云市场合作伙伴支持与服务了解阿里云首页云原生数据库 PolarDB云原生数据库 PolarDBPolarDB是阿里巴巴自研的新一代云原生数据库,在计算存储分离架构下,利用了软硬件结合的优势,为用户提供具备极致弹性、高性能、海量存储、安全可靠的数据库服务。100%兼容MySQL和PostgreSQL生态,高度兼容Oracle语法。'); 
    INSERT INTO t_chunk(chunk) VALUES('PolarDB产品系列介绍快速入门价格计算器资源包规格计算器相关技术圈PolarDB引擎版本PolarDB MySQL版多主多写、多活容灾、HTAP特性,交易性能高达开源数据库的6倍,分析性能高达开源数据库的400倍,TCO 低于自建数据库50%'); 
    INSERT INTO t_chunk(chunk) VALUES('PolarDB分布式版高吞吐、大存储、低延时、易扩展和超高可用的云时代数据库服务PolarDB PostgreSQL版快速弹性、高性能、海量存储、安全可靠的数据库服务,支持阿里云自研Ganos多维多模时空信息引擎及开源PostGIS地理信息引擎PolarDB PostgreSQL版(兼容Oracle)存储计算分离架构,软硬件结合,提供极致弹性、高性能、海量存储、安全可靠的数据库服务');
    INSERT INTO t_chunk(chunk) VALUES('体验教程免费云资源,真实云环境,沉浸式所见即所得体验丰富实践场景与解决方案PolarDB MySQL Serverless极致弹性体验Serverless动态弹性升降资源体验弹性过程中的无感伸缩和秒级弹升体验并观测Serverless的性能和价格力PolarDB MySQL无感秒切无需购买任何资源,真正免费体验在线体验热备“无感”“秒切”的效果'); 
    INSERT INTO t_chunk(chunk) VALUES('PolarDB MySQL列存索引IMCI体验IMCI对复杂查询的加速作用体验IMCI在OLAP场景下高效处理能力PolarDB MySQL弹性并行查询ePQ体验ePQ带来的查询加速体验ePQ带来的性能提升体验ePQ如何集群整体资源利用率PolarDB PostgreSQL Serverless极致弹性体验Serverless动态弹性升降资源体验弹性过程中的无感伸缩和秒级弹升体验并观测Serverless的性能和价格力');
    INSERT INTO t_chunk(chunk) VALUES('PolarDB PostgreSQL一站式HTAP体验主节点与分析节点之间的实时数据同步体验一站式HTAP下处理复杂查询SQL的高效能PolarDB-X透明分布式体验PolarDB-X的Auto Partitioning能力体验自动化拆分和分布式Online DDL能力体验数据回流及数据一致性的特点智能SQL转换领航助手体验基于规则的智能转换Prompt体验基于LLM的交互式智能订正Oracle迁移至PolarDB场景下的智能SQL转换助手RDS MySQL迁移至PolarDB MySQL版解决问题:容量过大,存不下解决问题:多副本复制延迟解决问题:增减节点耗时长Serverless高可用架构卓越效能极简运维');
    INSERT INTO t_chunk(chunk) VALUES('为什么选择阿里云什么是云计算全球基础设施技术领先稳定可靠安全合规分析师报告产品和定价全部产品免费试用');
    INSERT INTO t_chunk(chunk) VALUES('产品动态产品定价配置报价器云上成本管理解决方案技术解决方案文档与社区文档开发者社区天池大赛培训与认证权益中心免费试用高校计划企业扶持计划推荐返现计划支持与服务基础服务企业增值服务迁云服务官网公告健康看板信任中心');
  3. 生成向量数据。您可以通过创建自定义模型并调用实现文本转化向量。此处使用的是阿里云大模型服务平台百炼提供的text_embedding_v2模型。

    说明

    当前仅支持华北2(北京)区域的PolarDB PostgreSQL标准版集群调用内置模型text_embedding_v2,详细配置请参见如何快速执行文本转向量

    UPDATE t_chunk SET embedding =  polar_ai.ai_text_embedding(chunk);
  4. 创建检索所需索引。

    • 向量索引,此处使用的是L2距离,您可按需调整。

      CREATE INDEX ON t_chunk using hnsw(embedding vector_l2_ops);
    • 全文索引。

      UPDATE  t_chunk SET v = to_tsvector('jiebacfg', chunk);
      
      CREATE INDEX ON t_chunk USING rum (v rum_tsvector_ops);

检索

密集检索
稀疏检索
混合检索

只根据向量进行检索,距离越小表示相似度越高。

SELECT chunk, embedding <-> polar_ai.ai_text_embedding('PolarDB有哪些产品系列')::vector(1536) as dist
FROM t_chunk
ORDER by dist ASC
limit 5;

只根据全文进行检索,距离越小表示相似度越高。

SELECT chunk, v <=> to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速') as rank
FROM t_chunk 
WHERE v @@ to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速')
ORDER by rank ASC
LIMIT 5;

将两种查询方式的结果进行合并操作,以实现多路召回的能力。

WITH t AS (
SELECT chunk, embedding <-> polar_ai.ai_text_embedding('PolarDB有哪些产品系列')::vector(1536) as dist
FROM t_chunk
ORDER by dist ASC
limit 5 ),
t2 as (
  SELECT chunk, v <=> to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速') as rank
FROM t_chunk 
WHERE v @@ to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速')
ORDER by rank ASC
LIMIT 5
)
SELECT * FROM t
UNION ALL
SELECT * FROM t2;

由于这两种距离计算方法无法统一,因此需要采用RRF模型进行统一排名。RRF(Reciprocal Rank Fusion,倒数排名融合)是一种将具有不同相关性指标的多个结果集组合为单个结果集的方法,该方法无需调优,不同的相关性指标也不需要相互关联即可获得高质量的结果。基本步骤如下:

  1. 召回阶段收集排名

    多个检索器(各路召回)对其查询分别生成排序结果。

  2. 排名融合

    使用简单的评分函数(如倒数和)将各检索器的排名位置加权融合,公式如下:

    其中,为不同召回路的数量,是第个检索器对文档的排名位置,是一个平滑参数,通常取60。

  3. 综合排序

    根据融合后的评分对文档重新排序,生成最终结果。

在上述查询中,当您对查询结果排序不满意时,可调整参数改变结果顺序。根据查询时传递的参数,对全文检索和向量检索各自分别查询到的结果,按照公式对每一个返回的文档进行打分,其中表示某个文档排第位。如果文本结果中某个文档没有出现在密集向量检索的结果中,则该文档只有一个得分,同理稀疏向量结果中的文档情况亦然。如果某个文档同时出现在密集向量和稀疏向量的结果集中,则将各自计算的得分相加。

说明

平滑参数决定了每个查询的单个结果集中文档对最终排序结果的影响程度。数值越高,排名越低的文档对最终排序结果的影响越大。

-- 密集向量召回
WITH t1 as 
(
SELECT chunk, embedding <-> polar_ai.ai_text_embedding('PolarDB有哪些产品系列')::vector(1536) as dist
FROM t_chunk
ORDER by dist ASC
limit 5
),
t2 as (
SELECT ROW_NUMBER() OVER (ORDER BY dist ASC) AS row_num,
chunk
FROM t1
),
-- 稀疏向量召回
t3 as 
(
  SELECT chunk, v <=> to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速') as rank
  FROM t_chunk 
  WHERE v @@ to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速')
  ORDER by rank ASC
  LIMIT 5
),
t4 as (  
SELECT ROW_NUMBER() OVER (ORDER BY rank DESC) AS row_num,
chunk
FROM t3
),
-- 分别计算 RRF评分
t5 AS (
SELECT 1.0/(60+row_num) as score, chunk FROM t2
UNION ALL 
SELECT 1.0/(60+row_num), chunk FROM t4
)
-- 评分进行合并
SELECT sum(score) as score, chunk
FROM t5
GROUP BY chunk
ORDER BY score DESC;

按权重加权

您还可以为不同结果集设置不同权重,例如密集检索权重0.8,稀疏检索权重0.2。

-- 密集向量召回
WITH t1 as 
(
SELECT chunk, embedding <-> polar_ai.ai_text_embedding('PolarDB有哪些产品系列')::vector(1536) as dist
FROM t_chunk
ORDER by dist ASC
limit 5
),
t2 as (
SELECT ROW_NUMBER() OVER (ORDER BY dist ASC) AS row_num,
chunk
FROM t1
),
-- 稀疏向量召回
t3 as 
(
  SELECT chunk, v <=> to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速') as rank
  FROM t_chunk 
  WHERE v @@ to_tsquery('jiebacfg', 'PolarDB|PostgreSQL版|快速')
  ORDER by rank ASC
  LIMIT 5
),
t4 as (  
SELECT ROW_NUMBER() OVER (ORDER BY rank DESC) AS row_num,
chunk
FROM t3
),
-- 分别计算 RRF评分,权重分别为 0.8和0.2
t5 as (
SELECT (1.0/(60+row_num)) * 0.8 as score , chunk FROM t2
UNION ALL 
SELECT (1.0/(60+row_num)) * 0.2, chunk FROM t4
)
-- 评分进行合并
SELECT sum(score) as score, chunk
FROM t5
GROUP BY chunk
ORDER BY score DESC;
  • 本页导读 (1)
  • 背景
  • 最佳实践
  • 基础数据准备
  • 检索
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等