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

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

始める前に

RUM 拡張機能を作成するには、alloydb_superuser ロールが必要です。ロールの付与の詳細については、クラスタに 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 演算子クラスを使用して、タグのリストなどの配列の列にインデックスを作成します。これにより、他の配列と重複する配列(&&)、他の配列を含む配列 (@>)、他の配列に含まれる配列(<@)を効率的にクエリできます。次の例では、tags 列を documents テーブルに追加します。

  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. 汎用的な整数列(rating など)を documents テーブルに追加します。

    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. rating が値 5 に最も近いドキュメントを検索するクエリを実行します。

    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;
    

次のステップ