Setting up native PostgreSQL FTS
================================

``tsvector``
列、GINインデックス、および自動更新トリガーでソーステーブルを構成して、ハイブリッド検索クエリのキーワードレッグとしてネイティブのPostgreSQL全文検索FTSを使用します。追加の拡張機能は必要ありません。以下のすべての手順は、データベースで実行されるSQLコマンドです。セットアップには、タイトルの一致が本文の一致よりもランクが高いようにフィールドの重み付けと、行が挿入または更新されても検索列が最新の状態に保たれるようにトリガーが含まれます。

1. ``tsvector`` 列を追加します

``tsvector``
列を追加して、各行の前処理されたテキスト表現を保存します。これは、FTSインデックスが動作する列です。

.. code:: sql

      ALTER TABLE my_docs ADD COLUMN search_vector tsvector;

1. 列に重み付けフィールドを設定します

重み付けフィールドを使用して列にデータを入力して、さまざまなフィールドが関連性に影響を与える方法を制御します。重みA最高〜D最低を使用する
—
タイトルや概要などのフィールドに高い重みを割り当て、長い本文フィールドに低い重みを割り当てます。

.. code:: sql

      UPDATE my_docs
      SET search_vector =
          setweight(to_tsvector(english, coalesce(title,   )), A) ||
          setweight(to_tsvector(english, coalesce(summary, )), B) ||
          setweight(to_tsvector(english, coalesce(body,    )), C);

1. GINインデックスを作成する

``search_vector``
列にGIN一般逆引きインデックスを作成して、高速な全文検索を有効にします。このインデックスがないと、FTSクエリはシークエンシャル
スキャンを実行し、スケールしません。

.. code:: sql

      CREATE INDEX my_docs_fts_idx ON my_docs USING gin(search_vector);

1. 列を最新の状態に保つトリガーを作成します

新しい行および更新された行を自動的にトークン化するトリガーを設定して、手動更新せずにFTSインデックスの同期を維持します。

.. code:: sql

      CREATE OR REPLACE FUNCTION my_docs_search_vector_update()
      RETURNS trigger AS $$
      BEGIN
          NEW.search_vector :=
              setweight(to_tsvector(english, coalesce(NEW.title,   )), A) ||
              setweight(to_tsvector(english, coalesce(NEW.summary, )), B) ||
              setweight(to_tsvector(english, coalesce(NEW.body,    )), C);
          RETURN NEW;
      END;
      $$ LANGUAGE plpgsql;
      
      CREATE TRIGGER my_docs_search_vector_trigger
          BEFORE INSERT OR UPDATE ON my_docs
          FOR EACH ROW EXECUTE FUNCTION my_docs_search_vector_update();

1. テストクエリーを実行する

プレーンフレーズマッチングには\ ``plainto_tsquery``
を使用し、Googleスタイルの構文\ ``"exact phrase"`` 、\ ``-exclude``
、\ ``OR`` の場合は\ ``websearch_to_tsquery``
を使用します。アプリケーションのクエリ入力形式と一致するものを使用します。

.. code:: sql

      SELECT id, title,
             ts_rank_cd(search_vector, query) AS score
      FROM my_docs,
           plainto_tsquery(english, connection pooling) query
      WHERE search_vector @@ query
      ORDER BY score DESC
      LIMIT 10;

ネイティブFTSインデックスとともに実行されるAIDBパイプラインの場合、AIDBはエンベディング生成とベクター検索を処理します。
FTSトリガーとパイプラインは独立して動作するため、新しい行は両方によって自動的にカバーされます。

!!!note
上記のトリガーパターンにより、埋め込みが生成される前に到着した行であっても、FTSカバレッジが常に最新であることが保証されます。これにより、ネイティブFTSは、新しいコンテンツの信頼できるフォールバックになります。詳細については、
:ref:`Handling embedding service outages <Handling embedding service outages>` を参照してください。

--------------

次のステップ
------------

- :ref:`Writing hybrid search queries <Writing hybrid search queries>`  —
  重み付け線形フュージョンを含むハイブリッドクエリでFTSインデックスを使用します。

- :ref:`Handling embedding service outages <Handling embedding service outages>`  —
  埋め込みサービスが利用できない場合に、フォールバックとしてネイティブFTSを使用します。
