VECTOR_SEARCH函數用於向量相似性搜尋,支援大規模近似最近鄰尋找。
使用限制
VECTOR_SEARCH函數要求輸入表為Delta Table。
執行VECTOR_SEARCH函數前,建議對需要檢索的向量列資料建立VECTOR INDEX以加速大規模向量資料的相似性查詢,參考VECTOR INDEX。若檢索時未有可用的向量索引,系統會自動採用暴力搜尋,導致查詢較慢。
命令格式
VECTOR_SEARCH(
{ TABLE base_table | (base_table_query) }, -- 用於搜尋最近鄰嵌入向量的表
column_to_search, -- 指定基礎資料表中用於搜尋最近鄰嵌入向量的列名
{ TABLE query_table | (query_table_query) }, -- 提供待尋找最近鄰嵌入向量的表
query_column_to_search, -- 指定查詢表中包含待尋找最近鄰嵌入向量的列名
top_k -- top_k_value
[, distance_type] -- distance_type_value
[, options] -- json字串,其他可配置參數
)參數說明
參數 | 說明 | 注意事項 |
base_table | (base_table_query) | 必填。用於搜尋最近鄰嵌入向量的表。 |
|
query_table | (query_table_query) | 必填。提供待尋找最近鄰嵌入向量的表。 | |
column_to_search | 必填。指定基礎資料表中用於搜尋最近鄰嵌入向量的列名。 | |
query_column_to_search | 必填。指定查詢表中包含待尋找最近鄰嵌入向量的列名。 | |
top_k | 必填。指定要返回的最近鄰的數量。必須是一個正整數(即 ≥ 1)。 | |
distance_type | 選填。指定用於計算兩個向量之間距離的度量類型。三種類型均返回距離值,值越小表示兩個向量越接近。 ● euclidean(預設值):歐幾裡得距離,表示兩個向量在空間中的直線距離。 ● cosine:餘弦距離,用于衡量兩個向量方向的差異,常用於文本、映像特徵向量等情境。 ● dot_product:內積距離,適用於已歸一化的向量。 指定 distance_type 參數值無需使用單引號,例如指定為 cosine ,而非 'cosine' 。 | |
options | 選填。JSON 格式的字串,用於設定其他可配置參數。支援以下參數:
| |
傳回值說明
對於 query table 中的每一行,Vector Search 返回 base table 中滿足搜尋條件的資料。每個查詢行返回的結果行數由 top_k 指定。返回結果由以下三部分組成:
query table 輸出資料行:query table 中的全部列或SELECT 出來的列。
base table 輸出資料行:base table 中的全部列或SELECT 出來的列。
distance:DOUBLE 類型,表示 base table 與 query table 對應行之間的距離。
當 base/query 兩側存在同名列時,推薦使用限定列名訪問結果。詳情請參考樣本使用限定列名訪問結果。
使用樣本
資料準備
-- 開啟 VECTOR 資料類型
SET odps.sql.type.system.odps2=true;
SET odps.sql.type.vector.enable=true;
-- Base Table:動物向量表
CREATE TABLE IF NOT EXISTS animals (
name STRING,
category STRING,
vec VECTOR(FLOAT, 2)
)
TBLPROPERTIES (
"table.format.version"="2"
);
INSERT INTO animals VALUES
('dog', 'mammal', CAST(array(1.0, 2.0) AS VECTOR(FLOAT, 2))),
('wolf', 'mammal', CAST(array(2.0, 4.0) AS VECTOR(FLOAT, 2))),
('cat', 'mammal', CAST(array(1.0, 1.8) AS VECTOR(FLOAT, 2))),
('lion', 'mammal', CAST(array(2.0, -2.5) AS VECTOR(FLOAT, 2))),
('tiger', 'mammal', CAST(array(3.0, -2.0) AS VECTOR(FLOAT, 2))),
('otter', 'mammal', CAST(array(-3.0, -1.0) AS VECTOR(FLOAT, 2))),
('whale', 'mammal', CAST(array(-5.0, -1.0) AS VECTOR(FLOAT, 2))),
('snake', 'reptile', CAST(array(-2.0, 3.0) AS VECTOR(FLOAT, 2))),
('lizard','reptile', CAST(array(-1.8, 2.8) AS VECTOR(FLOAT, 2))),
('eagle', 'bird', CAST(array(5.0, -3.0) AS VECTOR(FLOAT, 2)));
-- Query Table:待查詢的動物向量表
CREATE TABLE IF NOT EXISTS query_animals (
query_name STRING,
tag STRING,
qvec VECTOR(FLOAT, 2)
)
TBLPROPERTIES (
"table.format.version"="2"
);
INSERT INTO query_animals VALUES
('dog-like', 'mammal', CAST(array(1.0, 2.0) AS VECTOR(FLOAT, 2))),
('cat-like', 'mammal', CAST(array(1.0, -1.0) AS VECTOR(FLOAT, 2))),
('snake-like','reptile', CAST(array(-2.0, 3.0) AS VECTOR(FLOAT, 2)));本文樣本中直接進行暴力搜尋,實際生產執行向量檢索Vector Search前,請先對需要搜尋的向量列建立Vector Index 並構建索引,請參考VECTOR INDEX,若未有可用的向量索引系統會自動採用暴力搜尋,導致查詢較慢。
表對錶檢索
在 animals 表的 vec 列中搜尋,為 query_animals 表的 qvec 列每一行找出最匹配的兩個向量。
SELECT _base.name, _query.query_name, distance
FROM VECTOR_SEARCH(
TABLE animals, vec,
TABLE query_animals, qvec,
2, EUCLIDEAN
);
-- 返回結果:
+--------+------------+---------------------+
| name | query_name | distance |
+--------+------------+---------------------+
| dog | dog-like | 0.0 |
| cat | dog-like | 0.04000001773238182 |
| lion | cat-like | 3.25 |
| tiger | cat-like | 5.0 |
| snake | snake-like | 0.0 |
| lizard | snake-like | 0.08000003546476364 |
+--------+------------+---------------------+Base 側簡單過濾
SELECT _base.name, _query.query_name, distance
FROM VECTOR_SEARCH(
(SELECT name, vec FROM animals WHERE category = 'mammal'), vec,
TABLE query_animals, qvec,
2, EUCLIDEAN
);
-- 返回結果:
+------+------------+------------+
| name | query_name | distance |
+------+------------+------------+
| dog | dog-like | 5.0 |
| wolf | dog-like | 5.0 |
| dog | cat-like | 2.0 |
| wolf | cat-like | 2.0 |
| dog | snake-like | 13.0 |
| wolf | snake-like | 13.0 |
+------+------------+------------+Base/Query 兩側都使用簡單子查詢
SELECT *
FROM VECTOR_SEARCH(
(SELECT name, vec FROM animals WHERE category IN ('mammal', 'reptile')), vec,
(SELECT query_name, qvec FROM query_animals WHERE tag = 'mammal'), qvec,
2, EUCLIDEAN
);
-- 返回結果:
+------------+---------+------+--------+------------+
| query_name | qvec | name | vec | distance |
+------------+---------+------+--------+------------+
| dog-like | [1, 2] | dog | [1, 2] | 5.0 |
| cat-like | [1, -1] | dog | [1, 2] | 2.0 |
| dog-like | [1, 2] | wolf | [2, 4] | 5.0 |
| cat-like | [1, -1] | wolf | [2, 4] | 2.0 |
+------------+---------+------+--------+------------+單個向量字面量檢索
SELECT _base.name, distance
FROM VECTOR_SEARCH(
TABLE animals, vec,
vector(1.0f, 2.0f) AS qt(qvec),
qvec,
3, COSINE
);
-- 返回結果:
+------+-----------------------+
| name | distance |
+------+-----------------------+
| dog | 5.960464477539063e-8 |
| wolf | 5.960464477539063e-8 |
| cat | 0.0009437799453735352 |
+------+-----------------------+使用限定列名訪問結果
當 base/query 兩側未顯式指定 alias 時,系統會自動產生預設 qualifier:base 側為 _base,query 側為 _query。推薦使用限定列名(如 _base.id、_query.id)訪問結果,存在同名列且未加限定時,未限定引用會報列名歧義。
-- 不推薦:如果兩側都有 name,會報 ambiguous
SELECT name
FROM VECTOR_SEARCH(TABLE animals, vec, TABLE animals, vec, 10, COSINE);
-- 返回報錯:
FAILED: ODPS-0130071:[1,8] Semantic analysis exception - name is ambiguous, can be both _query.name or _base.name
-- 推薦:使用預設 qualifier
SELECT _base.name, _query.query_name, distance
FROM VECTOR_SEARCH(
TABLE animals, vec,
TABLE query_animals, qvec,
2, COSINE
);
-- 返回結果:
+--------+------------+------------------------+
| name | query_name | distance |
+--------+------------+------------------------+
| dog | dog-like | 5.960464477539063e-8 |
| wolf | dog-like | 5.960464477539063e-8 |
| lion | cat-like | 0.006116271018981934 |
| tiger | cat-like | 0.019419312477111816 |
| snake | snake-like | -1.1920928955078125e-7 |
| lizard | snake-like | 0.00013881921768188477 |
+--------+------------+------------------------+
-- 也可以顯式指定 alias
SELECT b.name, q.query_name, distance
FROM VECTOR_SEARCH(
TABLE animals AS b, vec,
TABLE query_animals AS q, qvec,
2, COSINE
);
-- 返回結果:
+--------+------------+------------------------+
| name | query_name | distance |
+--------+------------+------------------------+
| dog | dog-like | 5.960464477539063e-8 |
| wolf | dog-like | 5.960464477539063e-8 |
| lion | cat-like | 0.006116271018981934 |
| tiger | cat-like | 0.019419312477111816 |
| snake | snake-like | -1.1920928955078125e-7 |
| lizard | snake-like | 0.00013881921768188477 |
+--------+------------+------------------------+不支援的情境樣本
Base 側不支援 Time Travel 文法
SELECT *
FROM VECTOR_SEARCH(
(SELECT name, vec FROM animals VERSION AS OF 1), vec,
TABLE query_animals, qvec,
10, COSINE
);
-- 返回報錯:
FAILED: ODPS-0130071:[3,4] Semantic analysis exception - VECTOR_SEARCH base table does not support time travelBase/Query 側不支援複雜輸入計劃
base/query 側輸入不能包含 JOIN、AGGREGATE 等複雜運算元。
SELECT *
FROM VECTOR_SEARCH(
(SELECT a.name, a.vec FROM animals a JOIN query_animals b ON a.name = b.query_name), vec,
TABLE query_animals, qvec,
10, COSINE
);
-- 返回報錯:
FAILED: ODPS-0130071:[] Semantic analysis exception - VECTOR_SEARCH input must be a simple plan containing only SELECT, FILTER, and TABLE SCAN operatorsBase/Query側的輸入表均不支援非Append Delta Table
-- 建立為普通表的Query table
CREATE Table query_table_animal AS
SELECT query_name, qvec FROM query_animals;
SELECT *
FROM VECTOR_SEARCH(
TABLE animals, vec,
TABLE query_table_animal, qvec,
10, COSINE
);
-- 返回報錯:
FAILED: ODPS-0130071:[] Semantic analysis exception - VECTOR_SEARCH input table must be an append delta tableQuery 側不支援多行 VALUES
Query側支援 0/1 行 VALUES,不支援多行 VALUES。
SELECT *
FROM VECTOR_SEARCH(
TABLE animals, vec,
(
SELECT query_name, qvec
FROM VALUES
('q1', vector(1.0f, 2.0f)),
('q2', vector(4.0f, 5.0f)) AS q(query_name, qvec)
),
qvec,
10, COSINE
);
-- 返回報錯:
FAILED: ODPS-0130071:[] Semantic analysis exception - VECTOR_SEARCH input table must be an append delta table