如何在带有杜松子酒的PostgreSQL中的非字符类型数据上创建tsvector_update_trigger?

时间:2018-03-11 17:22:22

标签: postgresql full-text-search

如何在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);

上述语句引发错误,指出statuslikes列是非字符类型。

尝试投射不赢的作品既不会抛出一个说明方法签名不匹配的错误:

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变量列。

1 个答案:

答案 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();

希望这对某人有用。