Halaman ini menjelaskan cara menemukan perkiraan tetangga terdekat (ANN) dan membuat kueri embedding vektor menggunakan fungsi jarak ANN.
Jika set data berukuran kecil, Anda dapat menggunakan K-nearest neighbors (KNN) untuk menemukan vektor k-terdekat yang tepat. Namun, seiring bertambahnya set data, latensi dan biaya penelusuran KNN juga meningkat. Anda dapat menggunakan ANN untuk menemukan perkiraan k-tetangga terdekat dengan latensi dan biaya yang jauh lebih rendah.
Dalam penelusuran ANN, vektor yang ditampilkan k bukanlah tetangga terdekat k teratas yang sebenarnya karena penelusuran ANN menghitung perkiraan jarak dan mungkin tidak melihat semua vektor dalam set data. Terkadang, beberapa vektor yang tidak termasuk dalam k-nearest neighbors teratas akan ditampilkan. Hal ini dikenal sebagai kerugian perolehan. Jumlah kerugian perolehan yang dapat diterima bergantung pada kasus penggunaan, tetapi dalam sebagian besar kasus, kehilangan sedikit perolehan sebagai imbalan atas peningkatan performa database adalah kompromi yang dapat diterima.
Untuk mengetahui detail selengkapnya tentang fungsi perkiraan jarak yang didukung di Spanner, lihat halaman referensi berikut untuk dialek database Anda:
- GoogleSQL
- PostgreSQL
Membuat kueri embedding vektor
Spanner mempercepat penelusuran vektor approximate nearest neighbor (ANN) menggunakan indeks vektor. Anda dapat menggunakan indeks vektor untuk mengkueri embedding vektor. Untuk mengkueri embedding vektor, Anda harus membuat indeks vektor terlebih dahulu. Kemudian, Anda dapat menggunakan salah satu dari tiga fungsi jarak perkiraan untuk menemukan ANN.
Batasan saat menggunakan fungsi jarak perkiraan mencakup hal berikut:
- Fungsi jarak perkiraan harus menghitung jarak antara kolom embedding dan ekspresi konstanta (misalnya, parameter atau literal).
- Output fungsi jarak perkiraan harus digunakan dalam klausa
ORDER BYsebagai satu-satunya kunci pengurutan, danLIMITharus ditentukan setelahORDER BY. - Kueri harus secara eksplisit memfilter baris yang tidak diindeks. Pada umumnya,
hal ini berarti kueri harus menyertakan klausa
WHERE <column_name> IS NOT NULLyang cocok dengan definisi indeks vektor, kecuali jika kolom sudah ditandai sebagaiNOT NULLdalam definisi tabel.
Untuk mengetahui daftar batasan yang mendetail, lihat halaman referensi fungsi jarak perkiraan.
Contoh
Pertimbangkan tabel Documents yang memiliki kolom DocEmbedding embedding teks yang telah dihitung sebelumnya dari kolom byte DocContents, dan kolom NullableDocEmbedding yang diisi dari sumber lain yang mungkin null.
Kedua kolom embedding menentukan panjang vektor 3, yang diperlukan untuk membuat indeks vektor untuk penelusuran ANN.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32>(vector_length=>3) NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>(vector_length=>3),
WordCount INT64
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE documents (
user_id bigint not null,
doc_id bigint not null,
author varchar(1024),
doc_contents bytea,
doc_embedding float4[] VECTOR LENGTH 3 not null,
nullable_doc_embedding float4[] VECTOR LENGTH 3,
word_count bigint,
PRIMARY KEY (user_id, doc_id)
);
Untuk menelusuri 100 vektor terdekat ke [1.0, 2.0, 3.0], tentukan salah satu
opsi penelusuran berikut dalam fungsi jarak perkiraan:
num_leaves_to_search: Jumlah leaf yang akan ditelusuri. Nilai harus berupa bilangan bulat positif.pct_leaves_to_search: Persentase leaf yang akan ditelusuri. Nilainya harus berupa double antara0.0dan100.0dengan tanda desimal eksplisit (misalnya,10.0). Indeks vektor yang dibuat sebelum November 2025 mungkin tidak mendukung opsi penelusuran ini.
Anda tidak dapat menentukan kedua opsi dalam fungsi jarak perkiraan yang sama.
Opsi 1. Gunakan opsi penelusuran num_leaves_to_search
GoogleSQL
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
Opsi 2. Gunakan opsi penelusuran pct_leaves_to_search
GoogleSQL
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"pct_leaves_to_search": 10.0}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"pct_leaves_to_search": 10.0}'
)
LIMIT 100;
Untuk menelusuri 100 vektor terdekat ke embedding yang dihasilkan oleh ekspresi SQL, gunakan pola berikut. Dalam contoh ini, kueri menemukan dokumen yang paling mirip dengan embedding UserId = 1 dan DocId = 1:
GoogleSQL
WITH emb AS (
SELECT DocEmbedding AS value
FROM Documents
WHERE UserId = 1 AND DocId = 1
LIMIT 1
)
SELECT DocId
FROM Documents, emb
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
emb.value, DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT documents.doc_id
FROM
documents,
(
SELECT doc_embedding AS value
FROM documents
WHERE user_id = 1 AND doc_id = 1
LIMIT 1
) vector
WHERE documents.doc_embedding IS NOT NULL
ORDER BY spanner.APPROX_EUCLIDEAN_DISTANCE(documents.doc_embedding,
vector.value, options=>'{"num_leaves_to_search": 10}'::jsonb)
LIMIT 100
Jika kolom embedding dapat bernilai null:
GoogleSQL
SELECT DocId
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
Menambahkan jarak ke hasil kueri
Dalam contoh sebelumnya, jarak ANN digunakan untuk mengurutkan hasil kueri, tetapi tidak ditampilkan dalam hasil tersebut. Untuk menambahkan jarak ke hasil, tempatkan fungsi jarak dalam klausa SELECT dan beri alias, lalu gunakan alias tersebut sebagai satu-satunya kunci pengurutan dalam klausa ORDER BY.
Contoh
GoogleSQL
SELECT DocId,
APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}') AS distance
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY distance
LIMIT 100
PostgreSQL
SELECT doc_id,
spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
) AS distance
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY distance
LIMIT 100;
Langkah berikutnya
Pelajari lebih lanjut indeks vektor Spanner.
Pelajari lebih lanjut fungsi perkiraan jarak di GoogleSQL dan PostgreSQL.
Pelajari lebih lanjut pernyataan indeks untuk GoogleSQL
VECTOR INDEXdan PostgreSQLINDEX.Pelajari lebih lanjut praktik terbaik indeks vektor.
Coba Mulai menggunakan Spanner Vector Search untuk contoh langkah demi langkah penggunaan ANN.