【问题标题】:How to create tsvector_update_trigger on Non-character type data in PostgreSQL with gin?如何使用 gin 在 PostgreSQL 中的非字符类型数据上创建 tsvector_update_trigger?
【发布时间】:2018-08-19 17:53:03
【问题描述】:

如何在 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 变体列的。

【问题讨论】:

    标签: postgresql full-text-search


    【解决方案1】:

    实现这一点的方法是创建一个我们可以转换的存储函数,然后将其传递给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();
    

    希望这对某人有用。

    【讨论】:

      猜你喜欢
      • 2021-12-18
      • 2023-03-19
      • 2019-01-09
      • 1970-01-01
      • 2016-09-20
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      相关资源
      最近更新 更多