1

我正在尝试在 PostgreSQL 9.2 中设置全文搜索。我创建了一个新表来保存我想要搜索的内容(以便我可以搜索许多不同类型的项目),如下所示:

CREATE TABLE search (
    target_id bigint PRIMARY KEY,
    target_type text,
    fts tsvector
);

CREATE INDEX search_fts ON search USING gin(fts);

每次将新项目插入(或更新)到我要搜索的各种表之一时,它都应该自动添加到search表中。假设我的表如下所示:

CREATE TABLE item (id bigint PRIMARY KEY, name text NOT NULL, description text);

我创建了一个触发器,传入我希望能够搜索的列名:

CREATE TRIGGER insert_item_search BEFORE INSERT
    ON item FOR EACH ROW EXECUTE PROCEDURE
    insert_search('{name, description}'::text[]);

然后创建了一个新函数insert_search

CREATE OR REPLACE FUNCTION insert_search(cols text[]) RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO search (target_id, target_type, fts) VALUES (
      NEW.id, TG_TABLE_NAME, to_tsvector('english', 'foo')
    );
    RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;

我的问题是,如何根据colsto传入表值to_tsvector?现在,该函数被调用并正确插入idand type,但我不知道根据cols参数动态获取其他值的正确方法。

4

2 回答 2

5

首先,要传递参数,只需直接发送它们:

CREATE TRIGGER insert_item_search BEFORE INSERT
    ON item FOR EACH ROW EXECUTE PROCEDURE
    insert_search('name', 'description');

而且,从 PL/pgSQL 你会得到这些参数作为一个数组,称为TG_ARGV. 但是,问题是 PL/pgSQL 无法NEW根据名称从记录中获取值。为此,您可以使用允许您这样做的语言(如 PL/python 或 PL/perl)或使用hstore扩展名.

我会坚持使用最后一个并使用hstore(除非您已经使用其他语言之一来创建函数):

CREATE OR REPLACE FUNCTION insert_search() RETURNS TRIGGER AS $$
DECLARE
        v_new hstore;
BEGIN
        v_new = hstore(NEW); -- convert the record to hstore
        FOR i IN 0..(TG_NARGS-1) LOOP
                INSERT INTO search (target_id, target_type, fts) VALUES (
                  NEW.id, TG_TABLE_NAME, to_tsvector('english', v_new -> TG_ARGV[i])
                );
        END LOOP;
    RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;

正如您在上面看到的,我使用hstore' 运算符->根据名称 (on TG_ARGV[i]) 获取值。

于 2013-02-22T19:08:49.100 回答
0

您可以使用变量访问触发器定义中指定的参数TG_ARGV。您可以在此处找到相关文档。 TG_ARGV是一个由基于 0 的索引访问的数组。所以它会像TG_ARGV[0],TG_ARGV[1]等等。

于 2013-02-22T18:44:41.067 回答