В настоящее время я пытаюсь реализовать Postgres текстовый поиск для моего приложения rails. Мои миграции успешно выполняются с созданием всех таблиц. Одна из моих миграций добавляет триггер для обновления столбца ts_vector (TSV) в моей таблице списков. Он выполняет связку в таблицах и две в промежуточных таблицах. Не уверен, что этот триггер самый эффективный, но он работает, когда вызывается процедурой.
CREATE OR REPLACE FUNCTION update_listings_tsv() RETURNS trigger AS $$
BEGIN
NEW.tsv := (
SELECT
setweight(to_tsvector(l.item_name), 'A') ||
setweight(to_tsvector(l.description), 'B') ||
setweight(to_tsvector(categories.name), 'B') ||
setweight(to_tsvector(sub_categories.name), 'B') ||
setweight(to_tsvector(sizes.name), 'B') ||
setweight(to_tsvector(users.username), 'C') ||
setweight(to_tsvector(string_agg(DISTINCT brands.name, ',')), 'A') ||
setweight(to_tsvector(string_agg(DISTINCT colours.name, ',')), 'B')
FROM listings l
JOIN users ON users.id = l.user_id
JOIN categories ON categories.id = l.category_id
JOIN sub_categories ON sub_categories.id = l.sub_category_id
JOIN sizes ON sizes.id = l.size_id
JOIN conditions ON conditions.id = l.condition_id
JOIN brands_listings ON brands_listings.listing_id = l.id
JOIN brands ON brands.id = brands_listings.brand_id
JOIN colours_listings ON colours_listings.listing_id = l.id
JOIN colours ON colours.id = colours_listings.colour_id
WHERE l.id = NEW.id
GROUP BY l.id, users.id, categories.id, sub_categories.id, sizes.id, conditions.id
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Вот в чем проблема:
Процедура обновления, которая вызывает триггер, работает нормально. Как и предполагалось, когда столбец списка обновляет столбец TSV для этого точного списка также обновляется.
CREATE TRIGGER tsvectorupdateupdate BEFORE UPDATE
ON listings FOR EACH ROW EXECUTE PROCEDURE update_listings_tsv();
Процедура вставки не работает. Я пробовал это ДО и ПОСЛЕ ВСТАВКИ. Я не знаю, где проблема. После сброса db: reset столбец TSV должен быть уже заполнен значением ts_vector.
CREATE TRIGGER tsvectorupdateinsert AFTER INSERT OR UPDATE
ON listings FOR EACH ROW EXECUTE PROCEDURE update_listings_tsv(tsv);