我正在尝试在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);
Run Code Online (Sandbox Code Playgroud)
每次将新项目插入(或更新)到我要搜索的各个表之一时,应将其自动添加到search表中。假设我的表如下所示:
CREATE TABLE item (id bigint PRIMARY KEY, name text NOT NULL, description text);
Run Code Online (Sandbox Code Playgroud)
我创建了一个触发器,该触发器传递了我希望能够搜索的列名:
CREATE TRIGGER insert_item_search BEFORE INSERT
ON item FOR EACH ROW EXECUTE PROCEDURE
insert_search('{name, description}'::text[]);
Run Code Online (Sandbox Code Playgroud)
然后创建一个新函数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;
Run Code Online (Sandbox Code Playgroud)
我的问题是,我该如何在基于表值传递cols给to_tsvector?目前,该函数正在被调用并正确插入id和type,但是我不知道基于cols参数动态获取其他值的正确方法。
首先,要传递参数,只需将其直接发送:
CREATE TRIGGER insert_item_search BEFORE INSERT
ON item FOR EACH ROW EXECUTE PROCEDURE
insert_search('name', 'description');
Run Code Online (Sandbox Code Playgroud)
并且,从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;
Run Code Online (Sandbox Code Playgroud)
如您在上面看到的,我使用hstore的运算符->根据名称(on TG_ARGV[i])获取值。
| 归档时间: |
|
| 查看次数: |
1095 次 |
| 最近记录: |