Membuat dan mengelola indeks RUM

Dokumen ini menunjukkan cara membuat ekstensi RUM dan membuat indeks untuk mengoptimalkan penelusuran teks lengkap di AlloyDB untuk PostgreSQL. Dokumen ini memberikan contoh untuk kasus penggunaan umum, termasuk peringkat, penelusuran frasa, dan pengurutan berdasarkan stempel waktu.

Sebelum memulai

Untuk membuat ekstensi RUM, Anda harus memiliki alloydbsuperuser peran database.

Peran IAM Admin AlloyDB (roles/alloydb.admin) memberikan kontrol penuh atas resource AlloyDB, tetapi tidak memberikan peran database alloydbsuperuser. Untuk membuat ekstensi, administrator harus secara eksplisit memberikan peran database alloydbsuperuser kepada Anda.

Untuk mengetahui informasi selengkapnya tentang pemberian peran, lihat Menambahkan akun pengguna atau layanan IAM ke cluster.

Membuat ekstensi RUM

Anda harus membuat ekstensi RUM sekali per database.

  1. Hubungkan ke database AlloyDB Anda menggunakan psql atau klien lain. Untuk mengetahui informasi selengkapnya, lihat Menghubungkan ke instance cluster.
  2. Jalankan perintah SQL berikut untuk membuat ekstensi:

    CREATE EXTENSION IF NOT EXISTS rum;
    

Membuat indeks RUM

Untuk mengoptimalkan kueri penelusuran teks lengkap, buat indeks RUM pada data Anda. RUM menawarkan beberapa class operator untuk berbagai kasus penggunaan.

Jenis class operator RUM

Tabel berikut merangkum berbagai class operator RUM dan kasus penggunaan utamanya.

Class Operator Kasus Penggunaan Utama Batasan
rum_tsvector_ops Penelusuran teks lengkap standar dengan peringkat dan penelusuran frasa. T/A
rum_tsvector_hash_ops Indeks yang lebih kecil dan update yang lebih cepat untuk penelusuran teks lengkap. Tidak mendukung penelusuran awalan.
rum_tsvector_addon_ops Penelusuran teks lengkap yang diurutkan berdasarkan kolom lain. T/A
rum_anyarray_ops Menelusuri dalam kolom array. T/A
rum_<TYPE>_ops Mengindeks jenis skalar untuk kueri berbasis jarak. T/A
rum_tsvector_hash_addon_ops Penelusuran teks lengkap berbasis hash yang diurutkan berdasarkan kolom lain. Tidak mendukung pencocokan awalan.
rum_tsquery_ops Mengindeks nilai tsquery yang disimpan untuk penelusuran terbalik. T/A
rum_anyarray_addon_ops Penelusuran array yang diurutkan berdasarkan kolom lain. T/A

Gunakan class operator rum_tsvector_ops untuk penelusuran teks standar yang memerlukan kemampuan peringkat dan penelusuran frasa yang cepat. Class operator ini menyimpan posisi setiap leksem dalam indeks. Contoh berikut membuat tabel bernama documents dengan kolom content.

  1. Buat tabel bernama 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. Isi tabel documents dengan data contoh:

    INSERT INTO documents (title, content) VALUES
      ('Title', 'This search engine is working as intended');
    
  3. Tambahkan kolom tsvector yang dibuat ke tabel Anda. Kolom ini secara otomatis menyimpan teks yang diproses dan meningkatkan performa kueri:

    ALTER TABLE documents
    ADD COLUMN search_vector tsvector
    GENERATED ALWAYS AS (to_tsvector('english', content)) STORED;
    
  4. Buat indeks RUM di kolom search_vector baru:

    CREATE INDEX idx_docs_rum
    ON documents
    USING rum (search_vector rum_tsvector_ops);
    
  5. Kueri tabel menggunakan indeks. Operator <=> menghitung skor relevansi, atau jarak, antara dokumen dan kueri langsung dari indeks, sehingga memungkinkan pengurutan cepat:

    SELECT title, content
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'search <-> engine')
    ORDER BY search_vector <=> to_tsquery('english', 'search <-> engine');
    
  6. Isi tabel documents dengan lebih banyak data:

    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. Jalankan kueri penelusuran awalan. Tindakan ini akan menemukan dokumen yang berisi kata-kata yang diawali dengan eng, seperti engineer atau english:

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

Gunakan class operator rum_tsvector_hash_ops untuk mengurangi ukuran indeks dan meningkatkan kecepatan update. Class ini menyimpan hash setiap leksem, bukan leksem lengkap. Pendekatan ini menghasilkan indeks yang lebih kecil, tetapi tidak mendukung penelusuran awalan. Contoh berikut mengasumsikan bahwa Anda memiliki tabel bernama documents dengan kolom search_vector.

  1. Buat indeks RUM menggunakan class operator hash:

    CREATE INDEX idx_docs_rum_hash
    ON documents
    USING rum (search_vector rum_tsvector_hash_ops);
    
  2. Isi tabel documents dengan lebih banyak data:

    INSERT INTO documents (title, content) VALUES ('Title3', 'That person was driving incredibly fast, however the routing was not very efficient');
    
  3. Jalankan kueri pencocokan standar:

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

Indeks untuk penelusuran yang diurutkan berdasarkan stempel waktu

Gunakan class operator rum_tsvector_addon_ops untuk mengoptimalkan kueri yang memfilter berdasarkan teks dan mengurutkan berdasarkan kolom lain, seperti stempel waktu. Pola ini menyimpan nilai kolom tambahan langsung dalam indeks, yang menghindari operasi pengurutan lambat setelah penelusuran. Contoh berikut mengasumsikan bahwa Anda memiliki tabel bernama documents dengan kolom search_vector dan kolom published_at.

  1. Buat indeks yang menyertakan stempel waktu 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. Jalankan kueri yang menemukan dokumen yang berisi kata engine dan mengurutkannya berdasarkan tanggal publikasi. Indeks menangani penelusuran dan pengurutan secara efisien:

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

Gunakan class operator rum_anyarray_ops untuk mengindeks kolom array, seperti daftar tag. Hal ini memungkinkan Anda membuat kueri secara efisien untuk array yang tumpang-tindih (&&), berisi (@>), atau berisi (<@) array lain. Contoh berikut menambahkan kolom tags ke tabel documents.

  1. Tambahkan kolom tags dan isi dengan data:

    ALTER TABLE documents 
    ADD COLUMN tags TEXT[];
    
    INSERT INTO documents (title, content, tags) VALUES ( 'Title4', 'Sample Text', ARRAY['ai', 'ml'] );
    
  2. Buat indeks RUM di kolom TEXT[] bernama tags:

    CREATE INDEX idx_tags_rum
    ON documents
    USING rum (tags rum_anyarray_ops);
    
  3. Jalankan kueri untuk menemukan dokumen yang memiliki ai atau ml di tag-nya:

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

Indeks untuk jenis skalar

Gunakan class operator rum_<TYPE>_ops untuk mengindeks kolom yang berisi nilai berkelanjutan, seperti bilangan bulat, stempel waktu, atau angka floating point. Class operator ini memungkinkan Anda menggunakan operator <=> untuk menghitung jarak antara nilai secara efisien. Contoh berikut mengasumsikan bahwa Anda memiliki tabel bernama documents.

  1. Tambahkan kolom bilangan bulat umum, seperti rating, ke tabel documents:

    ALTER TABLE documents
    ADD COLUMN rating INT;
    
    UPDATE documents 
    SET rating = floor(random() * 5 + 1);
    
  2. Buat indeks RUM di kolom rating:

    CREATE INDEX idx_rating_rum
    ON documents
    USING rum (rating rum_int4_ops);
    
  3. Jalankan kueri untuk menemukan dokumen dengan rating yang paling dekat dengan nilai 5:

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

Indeks untuk penelusuran hash yang dioptimalkan yang diurutkan berdasarkan stempel waktu

Gunakan class operator rum_tsvector_hash_addon_ops untuk menggabungkan manfaat indeks hash dengan kemampuan pengurutan indeks addon. Class ini menyimpan hash setiap leksem bersama dengan nilai kolom tambahan. Konfigurasi ini mendukung pengurutan yang efisien berdasarkan kolom tambahan, tetapi tidak mendukung pencocokan awalan. Contoh berikut mengasumsikan bahwa Anda memiliki tabel bernama documents dengan kolom search_vector dan kolom stempel waktu published_at.

  1. Buat indeks RUM yang menggunakan class operator hash dan menyertakan stempel waktu published_at:

    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. Jalankan kueri yang menemukan dokumen yang berisi engine dan mengurutkannya berdasarkan tanggal publikasi:

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

Indeks untuk kueri tersimpan

Gunakan class operator rum_tsquery_ops untuk mengindeks nilai tsquery. Hal ini memungkinkan Anda melakukan "penelusuran terbalik", yang mengidentifikasi kueri tersimpan mana yang cocok dengan dokumen input tertentu. Contoh berikut membuat tabel bernama queries.

  1. Buat tabel untuk menyimpan kueri:

    CREATE TABLE queries (
    query_text tsquery
    );
    INSERT INTO queries (query_text) VALUES (plainto_tsquery('AlloyDB is fast!'));
    
  2. Buat indeks RUM di kolom query_text:

    CREATE INDEX idx_queries_rum
    ON queries
    USING rum (query_text rum_tsquery_ops);
    
  3. Jalankan kueri untuk menemukan kueri tersimpan yang cocok dengan dokumen:

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

Indeks untuk penelusuran array yang diurutkan berdasarkan stempel waktu

Gunakan class operator rum_anyarray_addon_ops untuk mengindeks kolom array bersama dengan kolom tambahan untuk pengurutan. Contoh berikut mengasumsikan bahwa Anda memiliki tabel bernama documents dengan kolom tags dan kolom stempel waktu published_at.

  1. Buat indeks RUM di kolom tags yang menyertakan stempel waktu published_at:

    CREATE INDEX idx_tags_rum_timestamp
    ON documents
    USING rum (tags rum_anyarray_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'tags');
    
  2. Jalankan kueri untuk menemukan dokumen dengan tag ai, yang diurutkan berdasarkan tanggal publikasi:

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

Langkah berikutnya