Postgresql
tsvector_update_trigger 和 ts_vector 生成的列有什麼區別?
全文搜尋新手,我有一個feed_items表如下
feed_items (...title varchar, summary varchar, fullarticle varchar,...)
如果在標題中找到查詢,我想創建一個 ts_vector 列來從標題或摘要中搜尋具有更高優先級的查詢。
選項 1 我可以創建一個生成的列,如下所示
ALTER TABLE feed_items ADD COLUMN textsearchable_index_col tsvector GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(summary, ''))) STORED;
選項2 我可以像這樣在插入或更新後創建觸發器,下面的範例並不完美,我為title_vector和summary_vector創建了一個單獨的列,但我認為我需要將它們合併到一個列中,然後決定如何更加重視在標題中找到的查詢
ALTER TABLE "feed_items" ADD IF NOT EXISTS "title_vector" tsvector; COMMENT ON COLUMN "feed_items"."title_vector" IS $pga$vector representation of title$pga$; UPDATE feed_items SET title_vector = to_tsvector('english', title); CREATE INDEX "idx_title_vector" ON "feed_items" USING gin ("title_vector"); CREATE TRIGGER "trigger_update_title_vector" BEFORE INSERT OR UPDATE ON "feed_items" FOR EACH ROW EXECUTE PROCEDURE "tsvector_update_trigger"($pga$title_vector$pga$, $pga$pg_catalog.english$pga$, $pga$title$pga$);
我的主要問題是兩者之間有什麼區別?我應該使用哪一個?
觸發方法已過時。如果您使用的版本支持在表達式上使用生成的列,那麼您應該使用它們。如果你正在開始一個新項目,你絕對應該從一個至少是新的版本(v12)開始。
我認為這兩種方式都不理想,因為它們會保留不必要的數據。
我不會添加額外的列,而是在表達式上定義 GIN 索引:
CREATE INDEX ON feed_items USING gin ( to_tsvector('english', concat(title, ' ', summary)) );
concat
將 NULL 值視為空字元串,因此更簡單。然後您的全文搜尋將有
... WHERE to_tsvector('english', concat(title, ' ', summary)) @@ whatever