You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Supabase中pgvector自定义过滤SQL函数失效问题求助

问题描述

我在Supabase数据库中用pgvector存储嵌入向量,创建了documents表:

create table documents (
  id bigserial primary key,
  content text,
  embedding vector(1536),
  custom_id text -- 每个企业的自定义ID
);

接着编写了带custom_id参数的match_documents SQL函数,期望先过滤特定企业的文档,再执行向量相似度查询:

create or replace function match_documents (
  query_embedding vector (1536),
  match_threshold float,
  match_count int,
  custom_id text
) returns table (id bigint, content text, similarity float) language sql stable as $$
  select
    documents.id,
    documents.content,
    1 - (documents.embedding <=> query_embedding) as similarity
  from documents
  where documents.custom_id = match_documents.custom_id AND 1 - (documents.embedding <=> query_embedding) > match_threshold
  order by similarity desc
  limit match_count;
$$;

项目中调用该函数的代码如下:

const { data: documents, error } = await supabaseClient.rpc('match_documents', {
    query_embedding: embedding,
    match_threshold: .73, // 根据数据选择合适的阈值
    match_count: 10, // 选择匹配数量
    custom_id: "2",
  })

但实际调用时,custom_id的过滤条件并未生效,返回了不属于该ID的嵌入数据。请问如何实现先过滤文档再执行向量查询的逻辑?

解决方案

问题根源在于函数内的参数引用方式错误:match_documents.custom_id会被PostgreSQL识别为表的列(而非传入的函数参数),导致过滤条件失效。以下是两种修复方案:

方案1:重命名函数参数(推荐)

将函数参数名改为与表列名不同的名称,避免命名冲突,直接使用新参数名进行过滤:

create or replace function match_documents (
  query_embedding vector (1536),
  match_threshold float,
  match_count int,
  p_custom_id text -- 重命名参数,避免和表列custom_id冲突
) returns table (id bigint, content text, similarity float) language sql stable as $$
  select
    documents.id,
    documents.content,
    1 - (documents.embedding <=> query_embedding) as similarity
  from documents
  where documents.custom_id = p_custom_id -- 使用重命名后的参数
    AND 1 - (documents.embedding <=> query_embedding) > match_threshold
  order by similarity desc
  limit match_count;
$$;

调用时同步修改参数名:

const { data: documents, error } = await supabaseClient.rpc('match_documents', {
    query_embedding: embedding,
    match_threshold: .73,
    match_count: 10,
    p_custom_id: "2", // 对应函数的新参数名
  })

方案2:使用位置参数引用

如果不想修改参数名,可以通过参数的位置序号来引用(custom_id是第4个参数,对应$4):

create or replace function match_documents (
  query_embedding vector (1536),
  match_threshold float,
  match_count int,
  custom_id text
) returns table (id bigint, content text, similarity float) language sql stable as $$
  select
    documents.id,
    documents.content,
    1 - (documents.embedding <=> query_embedding) as similarity
  from documents
  where documents.custom_id = $4 -- 使用位置参数引用传入的custom_id
    AND 1 - (documents.embedding <=> query_embedding) > match_threshold
  order by similarity desc
  limit match_count;
$$;

这种写法无需修改调用代码,但可读性较差,不建议在参数较多时使用。

可选:优化查询性能

如果数据量较大,为了提升先过滤再向量查询的效率,可以创建custom_id与embedding的联合索引:

create index idx_documents_custom_id_embedding on documents using ivfflat (embedding vector_cosine_ops) where (custom_id is not null);

该索引会先过滤出对应custom_id的文档,再执行向量相似度匹配,大幅提升查询速度。

内容的提问来源于stack exchange,提问作者Santiago Padilla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:02:44