您好我正在尝试使用版本9.2.2学习如何在postgres中使用全文搜索。
Here is my database:
title : character varying(1024)
body : text
body_title_tsv | tsvector
然后我将body_title_tsv定义为由body和title字段组成的ts_vector,并使用coalesce来处理空值。
UPDATE pg_rocks_post SET body_title_tsv = to_tsvector( coalesce(body,'') || coalesce (title,''));
我想知道如何编写处理“title”和/或“body”更新的TRIGGER。
我知道我可以使用这样的语法和tsearch2函数创建一个Trigger。
CREATE TRIGGER body_title_tsv_trig BEFORE UPDATE OR INSERT on pg_rocks_post
FOR EACH ROW EXECUTE PROCEDURE tsearch2(body_title_tsv , title);
我可以用身体而不是标题来做同样的事情。
我的问题是如何将两者结合起来更新body_title_tsv
或者我是否必须学习如何编写基本上运行的函数 发生UPDATE时,body_title_tsv的SQL是什么? 。
我知道解决此问题的另一种方法是创建一个INDEX。但是我试图理解如何编写触发器并阅读Kory和Susan Douglas在PostgreSQL书中使用tsearch2的示例。
编辑:我遇到过这个功能。它的“tsvector_update_trigger”功能。我仍然有兴趣知道是否有办法使用tsearch2。
create trigger body_title_tsv_trig BEFORE UPDATE OR INSERT on pg_rocks_post FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(body_title_tsv,'pg_catalog.english',title,body);
答案 0 :(得分:1)
我会对此有所不同。您似乎希望为表提供一致的搜索界面,最好的方法是在函数中设计它。然后,您可以索引函数的输出。注意函数没有命中表,只对元组数据进行操作,这就是我们可以安全地索引其输出的原因。
CREATE OR REPLACE FUNCTION tsv(pg_rocks_post) RETURNS tsvector LANGUAGE SQL AS
$$
SELECT tsvector(coalesce($1.title, '') || ' ' || coalesce($1.body, ''));
$$;
现在我可以:
SELECT tsv(p) FROM pg_rocks_post p;
它会起作用。我也可以使用以下形式,在某些情况下会更有用:
SELECT p.tsv FROM pg_rocks_post.p;
或
SELECT * from pg_rocks_post p WHERE plainto_tsquery('fat cat') @@ p.tsv;
注意,由于p.tsv作为函数调用转换为tsv(p),因此无法省略表别名。这是一个很好的类似对象的语法糖,可以让你的PostgreSQL让你的生活更轻松。
下一步是索引函数的输出:
CREATE INDEX pg_rocks_post_tsv_idx ON pg_rocks_post(tsv(pg_rocks_post));
我们走了。不需要触发器,您可以获得派生数据的索引。