1

您好我正在尝试学习如何使用 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,并使用合并来处理空值。

UPDATE pg_rocks_post SET body_title_tsv = to_tsvector( coalesce(body,'') || coalesce (title,''));

我想知道如何编写一个处理“标题”和/或“正文”更新的触发器。

我知道我可以使用这样的语法和 tsearch2 函数来创建触发器。

    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?.

我知道解决这个问题的另一种方法是创建一个索引。但我试图了解如何编写触发器并阅读 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);
4

1 回答 1

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));

我们去吧。不需要触发器,您可以获得派生数据的索引。

于 2013-11-27T09:40:34.467 回答