Membuat dan mengelola indeks vektor

Halaman ini menjelaskan cara membuat dan mengelola indeks vektor Spanner, yang menggunakan penelusuran perkiraan tetangga terdekat (ANN) dan struktur berbasis pohon untuk mempercepat penelusuran kesamaan vektor pada data Anda.

Spanner mempercepat penelusuran vektor perkiraan tetangga terdekat (ANN) dengan menggunakan indeks vektor khusus. Indeks ini memanfaatkan Scalable Nearest Neighbor (ScaNN) dari Google Research, yaitu algoritma tetangga terdekat yang sangat efisien.

Indeks vektor menggunakan struktur berbasis pohon untuk mempartisi data dan memfasilitasi penelusuran yang lebih cepat. Spanner menawarkan konfigurasi pohon dua tingkat dan tiga tingkat:

  • Konfigurasi pohon dua tingkat: Node daun (num_leaves) berisi grup vektor yang terkait erat beserta centroid yang sesuai. Tingkat root terdiri dari sentroid dari semua node daun.
  • Konfigurasi pohon tiga tingkat: Mirip dengan konsep pohon dua tingkat, sekaligus memperkenalkan lapisan cabang tambahan (num_branches), yang sentroid node daunnya dipartisi lebih lanjut untuk membentuk tingkat root (num_leaves).

Spanner memilih indeks untuk Anda. Namun, jika Anda tahu bahwa indeks tertentu berfungsi paling baik, Anda dapat menggunakan petunjuk FORCE_INDEX untuk memilih menggunakan indeks vektor yang paling sesuai untuk kasus penggunaan Anda.

Untuk mengetahui informasi selengkapnya, lihat pernyataan VECTOR INDEX.

Batasan

  • Anda tidak dapat memisahkan indeks vektor terlebih dahulu. Untuk mengetahui informasi selengkapnya, lihat Ringkasan pra-pemisahan.

Membuat indeks vektor

Untuk mengoptimalkan recall dan performa indeks vektor, sebaiknya:

  • Buat indeks vektor Anda setelah sebagian besar baris dengan embedding ditulis ke database Anda. Anda mungkin juga perlu membangun ulang indeks vektor secara berkala setelah memasukkan data baru. Untuk mengetahui informasi selengkapnya, lihat Membangun ulang indeks vektor.

  • Gunakan klausa STORING untuk menyimpan salinan kolom dalam indeks vektor. Jika nilai kolom disimpan dalam indeks vektor, Spanner akan melakukan pemfilteran di tingkat leaf indeks untuk meningkatkan performa kueri. Sebaiknya simpan kolom jika digunakan dalam kondisi pemfilteran. Untuk mengetahui informasi selengkapnya tentang penggunaan STORING dalam indeks, lihat Membuat indeks untuk pemindaian khusus indeks.

Saat Anda membuat tabel, kolom sematan harus berupa array jenis data FLOAT32 (direkomendasikan) atau FLOAT64, dan memiliki anotasi vector_length, yang menunjukkan dimensi vektor.

Pernyataan DDL berikut membuat tabel Documents dengan kolom penyematan DocEmbedding dengan panjang vektor:

CREATE TABLE Documents (
  UserId INT64 NOT NULL,
  DocId INT64 NOT NULL,
  Author STRING (1024),
  DocContents Bytes(MAX),
  DocEmbedding ARRAY<FLOAT32>(vector_length=>128) NOT NULL,
  NullableDocEmbedding ARRAY<FLOAT32>(vector_length=>128),
  WordCount INT64,
) PRIMARY KEY (DocId);

Setelah mengisi tabel Documents, Anda dapat membuat indeks vektor dengan pohon dua tingkat dan 1.000 node daun pada tabel Documents dengan kolom embedding DocEmbedding menggunakan jarak kosinus:

CREATE VECTOR INDEX DocEmbeddingIndex
  ON Documents(DocEmbedding)
  STORING (WordCount)
  OPTIONS (distance_type = 'COSINE', tree_depth = 2, num_leaves = 1000);

Jika kolom sematan Anda tidak ditandai sebagai NOT NULL dalam definisi tabel, Anda harus mendeklarasikannya dengan klausa WHERE COLUMN_NAME IS NOT NULL dalam definisi indeks vektor, dengan COLUMN_NAME adalah nama kolom sematan Anda. Untuk membuat indeks vektor dengan pohon tiga tingkat dan 1000000 node daun pada kolom embedding yang dapat bernilai null NullableDocEmbedding menggunakan jarak kosinus:

CREATE VECTOR INDEX DocEmbeddingThreeLevelIndex
  ON Documents(NullableDocEmbedding)
  STORING (WordCount)
  WHERE NullableDocEmbedding IS NOT NULL
  OPTIONS (distance_type = 'COSINE', tree_depth = 3, num_branches=1000, num_leaves = 1000000);

Memfilter indeks vektor

Anda juga dapat membuat indeks vektor yang difilter untuk menemukan item yang paling mirip di database Anda yang cocok dengan kondisi filter. Indeks vektor yang difilter secara selektif mengindeks baris yang memenuhi kondisi filter yang ditentukan, sehingga meningkatkan performa penelusuran.

Dalam contoh berikut, tabel Documents2 memiliki kolom bernama Category. Dalam penelusuran vektor, kita ingin mengindeks kategori "Teknologi", jadi kita membuat kolom yang dihasilkan yang dievaluasi menjadi NULL jika kondisi kategori tidak terpenuhi.

CREATE TABLE Documents2 (
  DocId INT64 NOT NULL,
  Category STRING(MAX),
  NullIfFiltered BOOL AS (IF(Category = 'Tech', TRUE, NULL)) HIDDEN,
  DocEmbedding ARRAY<FLOAT32>(vector_length=>128),
) PRIMARY KEY (DocId);

Kemudian, kita membuat indeks vektor dengan filter. Indeks vektor TechDocEmbeddingIndex hanya mengindeks dokumen dalam kategori "Teknologi".

CREATE VECTOR INDEX TechDocEmbeddingIndex
  ON Documents2(DocEmbedding)
  STORING(NullIfFiltered)
  WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
  OPTIONS (...);

Saat menjalankan kueri berikut, yang memiliki filter yang cocok dengan TechDocEmbeddingIndex, Spanner akan otomatis memilih dan dipercepat oleh TechDocEmbeddingIndex. Kueri hanya menelusuri dokumen dalam kategori "Teknologi". Anda juga dapat menggunakan {@FORCE_INDEX=TechDocEmbeddingIndex} untuk memaksa Spanner menggunakan TechDocEmbeddingIndex secara eksplisit.

SELECT *
FROM Documents2
WHERE DocEmbedding IS NOT NULL AND NullIfFiltered IS NOT NULL
ORDER BY APPROX_(....)
LIMIT 10;

Langkah berikutnya