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
相关产品推荐
相关产品推荐

