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

検索したいさまざまなテーブルの 1 つに新しい項目が挿入 (または更新) されるたびに、自動的に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;

cols私の質問は、 to に基づいてテーブルの値を渡すにはどうすればよいto_tsvectorですか? 現在、関数が呼び出されてid正しく挿入されていますが、引数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;

上記のように、名前(on)に基づいて値を取得するためにhstore's演算子を使用しました。->TG_ARGV[i]

于 2013-02-22T19:08:49.100 に答える
0

変数を使用して、トリガー定義で指定されたパラメーターにアクセスできますTG_ARGV。これに関するドキュメントはこちらにあります。 TG_ARGV0 ベースのインデックスによってアクセスされる配列です。、 などのようTG_ARGV[0]TG_ARGV[1]なります。

于 2013-02-22T18:44:41.067 に答える