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