VECTOR_SEARCH

更新时间:
复制 MD 格式

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)

必填。用于搜索最近邻嵌入向量的表。

  • base_table_query 和query_table_query 输入仅支持由 TABLE SCAN、FILTER、SELECT 及 TABLE ALIAS 算子组成的简单链路。不支持复杂输入如:JOIN、GROUP BY/ AGGREGATE、UNION、WINDOWORDER BY/LIMIT等导致复杂执行计划的场景。详情请参考示例Base/Query 侧不支持复杂输入计划

  • base_table_query/query_table_query 支持显式指定别名alias;如果没有显式指定 alias,系统会为 Base 侧和 Query 侧自动生成默认 qualifier:base 侧:`_base` ,query 侧:`_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 格式的字符串,用于设置其他可配置参数。支持以下参数:

  • use_brute_force:JSON布尔值,指定是否使用暴力搜索(即跳过可用的向量索引),默认值为 false。

    • '{"use_brute_force":true}'即使用暴力搜索。

    • 若指定该参数为 false 但无可用向量索引时,系统仍会自动采用暴力搜索。

返回值说明

对于 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 travel

Base/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 operators

Base/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 table

Query 侧不支持多行 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