Postgresql

tsvector_update_trigger 和 ts_vector 生成的列有什麼區別?

  • December 3, 2021

全文搜尋新手,我有一個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

引用自:https://dba.stackexchange.com/questions/303412