RUM インデックスを作成して管理する

このドキュメントでは、RUM 拡張機能を作成し、AlloyDB for PostgreSQL で全文検索を最適化するためのインデックスを作成する方法について説明します。ランキング、フレーズ検索、タイムスタンプによる並べ替えなど、一般的なユースケースの例を示します。

始める前に

RUM 拡張機能を作成するには、alloydbsuperuser データベース ロールが必要です。

AlloyDB 管理者(roles/alloydb.admin)IAM ロールは、AlloyDB リソースに対する完全な制御権を付与しますが、alloydbsuperuser データベース ロールは付与しません。拡張機能を作成するには、管理者が alloydbsuperuser データベース ロールを明示的に付与する必要があります。

ロールの付与の詳細については、IAM ユーザーまたはサービス アカウントをクラスタに追加するをご覧ください。

RUM 拡張機能を作成する

RUM 拡張機能は、データベースごとに 1 回作成する必要があります。

  1. psql または別のクライアントを使用して AlloyDB データベースに接続します。詳細については、クラスタ インスタンスに接続するをご覧ください。
  2. 次の SQL コマンドを実行して、拡張機能を作成します。

    CREATE EXTENSION IF NOT EXISTS rum;
    

RUM インデックスを作成する

全文検索クエリを最適化するには、データに RUM インデックスを作成します。RUM には、さまざまなユースケースに対応する複数の演算子クラスが用意されています。

RUM 演算子クラスの種類

次の表に、さまざまな RUM オペレーター クラスとその主なユースケースを示します。

演算子クラス 主なユースケース 制限事項
rum_tsvector_ops ランキングとフレーズ検索を備えた標準の全文検索。 なし
rum_tsvector_hash_ops 全文検索のインデックスが小さくなり、更新が高速化されます。 接頭辞検索はサポートされていません。
rum_tsvector_addon_ops 別の列で並べ替えられた全文検索。 なし
rum_anyarray_ops 配列の列内の検索。 なし
rum_<TYPE>_ops 距離ベースのクエリのスカラー型のインデックス登録。 なし
rum_tsvector_hash_addon_ops 別の列で並べ替えられたハッシュベースの全文検索。 接頭辞の一致はサポートされていません。
rum_tsquery_ops 逆検索用に保存された tsquery 値のインデックス登録。 なし
rum_anyarray_addon_ops 別の列で並べ替えられた配列検索。 なし

高速なランキングとフレーズ検索機能を必要とする標準のテキスト検索には、rum_tsvector_ops 演算子クラスを使用します。この演算子クラスは、インデックス内の各レクシムの位置を保存します。次の例では、content 列を持つ documents という名前のテーブルを作成します。

  1. documents という名前のテーブルを作成します。

    CREATE TABLE documents (
      id SERIAL PRIMARY KEY,
      title TEXT NOT NULL,
      content TEXT NOT NULL,
      published_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
    );
    
  2. documents テーブルにサンプルデータを入力します。

    INSERT INTO documents (title, content) VALUES
      ('Title', 'This search engine is working as intended');
    
  3. テーブルに生成された tsvector 列を追加します。この列には、処理されたテキストが自動的に保存され、クエリのパフォーマンスが向上します。

    ALTER TABLE documents
    ADD COLUMN search_vector tsvector
    GENERATED ALWAYS AS (to_tsvector('english', content)) STORED;
    
  4. 新しい search_vector 列に RUM インデックスを作成します。

    CREATE INDEX idx_docs_rum
    ON documents
    USING rum (search_vector rum_tsvector_ops);
    
  5. インデックスを使用してテーブルをクエリします。<=> 演算子は、ドキュメントとクエリの関連性スコアまたは距離をインデックスから直接計算し、高速な並べ替えを可能にします。

    SELECT title, content
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'search <-> engine')
    ORDER BY search_vector <=> to_tsquery('english', 'search <-> engine');
    
  6. documents テーブルにデータを追加します。

    INSERT INTO documents (title, content) VALUES ('Title1', 'English is my primary language.');
    INSERT INTO documents (title, content) VALUES ('Title2', 'Google has a great engineering culture');
    
  7. 接頭辞検索クエリを実行します。これにより、engineerenglish など、eng で始まる単語を含むドキュメントが検索されます。

    SELECT title, content
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'eng:*');
    

rum_tsvector_hash_ops 演算子クラスを使用して、インデックス サイズを縮小し、更新速度を向上させます。このクラスは、完全なレクシームではなく、各レクシームのハッシュを保存します。このアプローチでは、インデックスは小さくなりますが、プレフィックス検索はサポートされません。次の例では、search_vector 列を含む documents という名前のテーブルがあることを前提としています。

  1. ハッシュ オペレーター クラスを使用して RUM インデックスを作成します。

    CREATE INDEX idx_docs_rum_hash
    ON documents
    USING rum (search_vector rum_tsvector_hash_ops);
    
  2. documents テーブルにデータを追加します。

    INSERT INTO documents (title, content) VALUES ('Title3', 'That person was driving incredibly fast, however the routing was not very efficient');
    
  3. 標準一致クエリを実行します。

    SELECT * FROM documents WHERE search_vector @@ to_tsquery('english', 'fast & efficient');
    
    

タイムスタンプで並べ替えられた検索のインデックス

rum_tsvector_addon_ops 演算子クラスを使用して、テキストでフィルタリングし、タイムスタンプなどの別のフィールドで並べ替えるクエリを最適化します。このパターンでは、追加フィールドの値がインデックスに直接保存されるため、検索後のソート処理が遅くなるのを回避できます。次の例では、search_vector 列と published_at 列を含む documents という名前のテーブルがあることを前提としています。

  1. published_at タイムスタンプを含むインデックスを作成します。

    CREATE INDEX idx_docs_rum_timestamp
    ON documents
    USING rum (search_vector rum_tsvector_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'search_vector');
    
  2. 単語 engine を含むドキュメントを検索し、出版日で並べ替えるクエリを実行します。インデックスは検索と並べ替えの両方を効率的に処理します。

    SELECT title, published_at
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'engine')
    ORDER BY published_at DESC;
    

rum_anyarray_ops 演算子クラスを使用して、タグのリストなどの配列列にインデックスを付けます。これにより、重複する(&&)、含む(@>)、または他の配列に含まれる(<@)配列を効率的にクエリできます。次の例では、documents テーブルに tags 列を追加します。

  1. tags 列を追加して、データを入力します。

    ALTER TABLE documents 
    ADD COLUMN tags TEXT[];
    
    INSERT INTO documents (title, content, tags) VALUES ( 'Title4', 'Sample Text', ARRAY['ai', 'ml'] );
    
  2. tags という名前の TEXT[] 列に RUM インデックスを作成します。

    CREATE INDEX idx_tags_rum
    ON documents
    USING rum (tags rum_anyarray_ops);
    
  3. タグに ai または ml が含まれているドキュメントを検索するクエリを実行します。

    SELECT * FROM documents WHERE tags && '{"ai", "ml"}';
    

スカラー型のインデックス

rum_<TYPE>_ops 演算子クラスを使用して、整数、タイムスタンプ、浮動小数点数などの連続値を含む列にインデックスを付けます。これらの演算子クラスを使用すると、<=> 演算子を使用して値間の距離を効率的に計算できます。次の例では、documents という名前のテーブルがあることを前提としています。

  1. documents テーブルに rating などの汎用整数列を追加します。

    ALTER TABLE documents
    ADD COLUMN rating INT;
    
    UPDATE documents 
    SET rating = floor(random() * 5 + 1);
    
  2. rating 列に RUM インデックスを作成します。

    CREATE INDEX idx_rating_rum
    ON documents
    USING rum (rating rum_int4_ops);
    
  3. クエリを実行して、値 5 に最も近い rating を持つドキュメントを見つけます。

    SELECT title, rating
    FROM documents
    ORDER BY rating <=> 5;
    

タイムスタンプで並べ替えられた最適化されたハッシュ検索のインデックス

rum_tsvector_hash_addon_ops 演算子クラスを使用して、ハッシュ インデックスの利点とアドオン インデックスの並べ替え機能を組み合わせます。このクラスは、各レクシームのハッシュと追加の列の値を保存します。この構成では、追加の列による効率的な並べ替えはサポートされますが、プレフィックス マッチングはサポートされません。次の例では、search_vector 列と published_at タイムスタンプ列を含む documents という名前のテーブルがあることを前提としています。

  1. ハッシュ オペレーター クラスを使用し、published_at タイムスタンプを含む RUM インデックスを作成します。

    CREATE INDEX idx_docs_rum_hash_timestamp
    ON documents
    USING rum (search_vector rum_tsvector_hash_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'search_vector');
    
  2. engine を含むドキュメントを検索し、出版日で並べ替えるクエリを実行します。

    SELECT title, published_at
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'engine')
    ORDER BY published_at DESC;
    

保存済みクエリのインデックス

rum_tsquery_ops 演算子クラスを使用して tsquery 値をインデックス登録します。これにより、「逆検索」を実行して、指定された入力ドキュメントに一致する保存済みクエリを特定できます。次の例では、queries という名前のテーブルを作成します。

  1. クエリを保存するテーブルを作成します。

    CREATE TABLE queries (
    query_text tsquery
    );
    INSERT INTO queries (query_text) VALUES (plainto_tsquery('AlloyDB is fast!'));
    
  2. query_text 列に RUM インデックスを作成します。

    CREATE INDEX idx_queries_rum
    ON queries
    USING rum (query_text rum_tsquery_ops);
    
  3. クエリを実行して、ドキュメントと一致する保存済みクエリを見つけます。

    SELECT *
    FROM queries
    WHERE to_tsvector('english', 'AlloyDB is fast') @@ query_text;
    

タイムスタンプで並べ替えられた配列検索のインデックス

rum_anyarray_addon_ops 演算子クラスを使用して、配列列と並べ替え用の追加列をインデックスに登録します。次の例では、tags 列と published_at タイムスタンプ列を持つ documents という名前のテーブルがあることを前提としています。

  1. published_at タイムスタンプを含む tags 列に RUM インデックスを作成します。

    CREATE INDEX idx_tags_rum_timestamp
    ON documents
    USING rum (tags rum_anyarray_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'tags');
    
  2. ai タグが付いたドキュメントを出版日で並べ替えて検索するクエリを実行します。

    SELECT title, published_at
    FROM documents
    WHERE tags @> '{"ai"}'
    ORDER BY published_at DESC;
    

次のステップ