如何在PostgreSQL中使用gin为非字符数据类型创建tsvector更新触发器以获得全文搜索支持?
例如,具有posts
表的情况具有:
title
(varchar)text
(varchar)status
(枚举['已发布','草稿'] likes
(整数)我已经创建了一个索引列:
ALTER TABLE "posts" ADD COLUMN "posts_full_text" TSVECTOR';
UPDATE "posts" SET "posts_full_text" = to_tsvector('english', title || ' ' || text || ' ' || status || ' ' || likes);
CREATE INDEX np_search_idx ON "posts" USING gin("posts_full_text");
然后尝试创建更新触发器:
CREATE TRIGGER update_posts_tsvector BEFORE INSERT OR UPDATE
ON posts FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger("posts", 'pg_catalog.english', title, text, status, likes);
上述语句引发错误,指出status
和likes
列是非字符类型。
尝试投射不赢的作品既不会抛出一个说明方法签名不匹配的错误:
CREATE TRIGGER update_posts_tsvector BEFORE INSERT OR UPDATE
ON posts FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger("posts", 'pg_catalog.english', title, text, status::VARCHAR, likes::VARCHAR);
因此,通过这种方式不可能在实现转换策略之前索引非char变量列。
答案 0 :(得分:0)
实现这一目标的方法是创建一个存储函数,我们可以将其转换为to_tsvector()
而不是tsvector_update_trigger()
:
CREATE OR REPLACE FUNCTION update_posts_tsvector() RETURNS trigger AS $$
begin
new."posts" :=
setweight(to_tsvector('pg_catalog.english', coalesce(new.title,'')), 'A') ||
setweight(to_tsvector('pg_catalog.english', coalesce(new.text,'')), 'B') ||
setweight(to_tsvector('pg_catalog.english', coalesce(new.status::TEXT,'')), 'B') ||
setweight(to_tsvector('pg_catalog.english', coalesce(new.likes::TEXT,'')), 'B');
return new;
end
$$ LANGUAGE plpgsql;
(我们可以省略setweight
包装方法,只需直接使用to_tsvector
)
然后将该函数绑定到我们的更新触发器:
CREATE TRIGGER np_vector_update BEFORE INSERT OR UPDATE ON "posts" FOR EACH ROW EXECUTE PROCEDURE update_posts_tsvector();
希望这对某人有用。