tsvector_update_trigger 不能生成摘要,因其仅为 PostgreSQL 内置 C 函数,仅执行分词拼接并输出 tsvector 类型(如 'optimiz':1A,3B'),不调用大模型,也不支持语义提炼或文本压缩,设计上完全不涵盖摘要功能。

直接用 tsvector_update_trigger 只能生成词向量,不能生成自然语言摘要;摘要必须靠外部模型(如 azure_ai 扩展或自定义 PL/pgSQL 调用 HTTP),而词向量可由 PostgreSQL 原生函数全自动完成。两者技术路径完全不同,混在一起写触发器会失败。
为什么不能用 tsvector_update_trigger 生成摘要
tsvector_update_trigger 是 PostgreSQL 内置的 C 函数,只做分词拼接,输出是 tsvector 类型(比如 ''optimiz':1A,3B 'perfom':2A'),不是人类可读的句子。它不调用任何大模型,也不支持文本压缩、语义提炼——这根本不在它的设计范围内。
常见错误包括:
- 误以为加个参数就能出摘要,比如写
tsvector_update_trigger('summary', 'chinese', title, content)—— 这只会报错“function cannot be called directly” - 在触发器里硬塞
pg_notify去调外部服务,但没处理超时、重试、失败回滚,导致摘要列长期为空且无告警
词向量自动更新:用 tsvector_update_trigger 的正确姿势
这是 PostgreSQL 原生支持的轻量方案,适合搜索场景。关键不是“能不能”,而是“怎么配才不翻车”:
- 目标列(如
search_vector)必须已存在,类型为tsvector - 触发器必须写成
BEFORE INSERT OR UPDATE,AFTER无效 - 第二个参数推荐全路径配置,例如
'pg_catalog.chinese',避免search_path变更导致分词失效 - 文本字段名(如
title,content)绝对不能加单引号;加了就变成字符串字面量,不是取字段值
正确示例:
CREATE TRIGGER tr_articles_search_vector
BEFORE INSERT OR UPDATE ON articles
FOR EACH ROW
EXECUTE FUNCTION tsvector_update_trigger(
search_vector,
'pg_catalog.chinese',
title,
content
);
摘要生成:必须绕开 tsvector_update_trigger,走异步或扩展路线
PostgreSQL 本身不提供摘要能力,但可通过以下两种方式接入:
- 用
azure_ai扩展(Azure DB for PostgreSQL 灵活服务器):注册自动摘要任务,指定源字段和目标TEXT列,后台调用 Azure AI 模型,结果写回。一行 SQL 启动:SELECT azure_ai.register_summary_task(...) - 自建 PL/pgSQL 函数 + 外部 HTTP 客户端(如
http_post):触发器内发起请求,但必须设WHEN (TG_OP = 'INSERT' OR (TG_OP = 'UPDATE' AND OLD.content IS DISTINCT FROM NEW.content))避免无意义重试
注意:同步调用外部 API 会阻塞事务,一旦网络抖动或模型超时,整个 INSERT/UPDATE 就卡住。生产环境务必异步化,且摘要列要允许为 NULL,失败时不中断主流程。
容易被忽略的细节:触发器生效但列仍为空
这不是代码写错了,而是数据没真正“变”:
-
UPDATE articles SET title = title—— 值未变,PostgreSQL 优化器跳过触发器执行 - 用了
SET col = DEFAULT或DEFAULT值本身为空,COALESCE没兜底,导致to_tsvector输入空串,输出空tsvector - 触发器被禁用:查
SELECT tgname, tgenabled FROM pg_trigger WHERE tgrelid = 'articles'::regclass,tgenabled必须是O
验证是否真生效,别看日志,直接插入后立刻查:SELECT search_vector, title, content FROM articles ORDER BY id DESC LIMIT 1。空值不是 bug,是输入或配置问题。

















