Oracle LiveLabs实验:Oracle AI Vector Search - Basics

本文为Oracle LiveLabs中实验Oracle AI Vector Search - Basics的过程记录。

这个实验的作者是 Doug Hood,贡献者为Sean Stacey。

简介

Oracle AI Vector Search 包含一套复杂的功能,使开发人员能够在 Oracle 数据库环境中无缝存储、索引和搜索矢量数据。矢量数据以多维数字数组表示,在捕获非结构化数据(包括图像、文本、音频和视频)中的各种特征方面发挥着关键作用。

Oracle Vector Database 的关键组件包括:

  • 矢量数据类型:一种创新的数据类型,旨在将矢量数据直接存储在 Oracle 数据库中,促进无缝集成。

  • 矢量索引:专门的索引机制,针对快速高效地检索相似矢量进行了优化,提高了数据库的搜索效率。

  • 矢量搜索 SQL 运算符:这些新颖的 SQL 运算符专为对矢量数据进行复杂的相似性搜索而量身定制,为开发人员提供了探索和分析复杂数据集的强大工具。

这些新功能还支持检索增强生成 (RAG),这是一种突破性的生成式 AI 技术,它结合了大型语言模型 (LLM) 和私有业务数据来提供对自然语言问题的回答。 RAG 通过使用来自客户 Vector 数据库的企业数据增强 LLM 查询来提供更高的准确性并避免幻觉。

为什么要使用 Oracle Database AI Vector Search?Oracle Database AI Vector Search 的最大好处是,非结构化数据的语义搜索可以与业务数据的关系搜索结合在一个系统中。

这不仅功能强大,而且效率更高,因为您不需要添加专门的 Vector 数据库,从而消除了多个系统之间数据碎片化的痛苦。

例如,您可以使用一个应用程序来查找与您拍摄的喜欢的房子的照片相似的房子,该房子位于您喜欢的区域,预算一定。在这种情况下,找到一个好的匹配需要将语义图片搜索与业务数据搜索相结合。

在本研讨会中,您将学习如何:

  • 在 Oracle 23ai Free 数据库中使用 Vectors。
  • Vectors 上的基本查询和 DML 操作。
  • 使用 Vector_distance 函数查找最近的向量
  • 使用属性过滤缩小搜索结果
  • 使用 AI 向量搜索的附加函数

实验1:矢量 DDL、DML 和查询

在本实验中,我们将研究如何使用 Vector 数据和常规关系表。完成本实验后,您将看到:

  • 使用 Vector 列创建表是多么容易。
  • 对 Vector 列执行 DDL(数据定义语言)操作。
  • 如何将常规 DML(数据操作语言)操作与 Vector 列一起使用。

我们将首先创建一个包含单个 Vector 列的表,插入几行并查询该表。

在本实验中,您将了解如何执行以下向量操作:

  • 任务 1 - 在表中创建向量
  • 任务 2 - 将向量插入向量表
  • 任务 3 - 从向量中选择值
  • 任务 4 - 更新向量
  • 任务 5 - 对向量执行 DML 操作
  • 任务 6 - 具有多个向量的表
  • 任务 7 - 对具有固定维度的向量执行操作
  • 任务 8 - 创建具有多维向量的表
  • 任务 9 - 对向量执行 DDL 操作
  • 任务 10 - 不允许的向量操作

连接到您的矢量数据库

实验环境包括预安装的 Oracle 23ai 免费数据库,其中包括 Oracle AI Vector Search。我们将从名为 orclpdb1 的可插拔数据库运行实验室练习,并以用户 vector 和密码 vector 的身份连接到数据库

sql 复制代码
[ORCLCDB:oracle@aivs:~]$ sqlplus vector/vector@orclpdb1

SQL*Plus: Release 23.0.0.0.0 - Limited Availability on Thu Feb 20 08:28:17 2025
Version 23.4.0.24.02

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

ERROR:
ORA-28098: Profile limits PASSWORD_LIFE_TIME and PASSWORD_GRACE_TIME are not
unlimited, password will expire within 7 days.
Help: https://docs.oracle.com/error-help/db/ora-28098/


Last Successful login time: Fri Apr 19 2024 15:55:20 +00:00

Connected to:
Oracle Database 23c Enterprise Edition Release 23.0.0.0.0 - Limited Availability
Version 23.4.0.24.02

SQL>

任务 1 - 在表中创建向量

sql 复制代码
DROP TABLE IF EXISTS t1;  

CREATE TABLE IF NOT EXISTS t1 (v  vector);

DESC t1

输出为:

sql 复制代码
SQL> desc t1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 V                                                  VECTOR(*, *)

任务 2 - 将向量插入向量表

sql 复制代码
INSERT INTO t1 VALUES ('[1.1, 2.7, 3.141592653589793238]'),
                      ('[9.34, 0.0, -6.923]'),
                      ('[-2.01, 5, -25.8]'),
                      ('[-8.2, -5, -1013.6]'),
                      ('[7.3]'),
                      ('[2.9]'),   
                      ('[1, 2, 3, 4, 5]') ;

7 rows created.

任务 3 - 从向量中选择值

sql 复制代码
SQL> SELECT * FROM t1;

V
--------------------------------------------------------------------------------
[1.10000002E+000,2.70000005E+000,3.14159274E+000]
[9.34000015E+000,0,-6.92299986E+000]
[-2.00999999E+000,5.0E+000,-2.57999992E+001]
[-8.19999981E+000,-5.0E+000,-1.01359998E+003]
[7.30000019E+000]
[2.9000001E+000]
[1.0E+000,2.0E+000,3.0E+000,4.0E+000,5.0E+000]

7 rows selected.

任务 4 - 更新向量

sql 复制代码
UPDATE t1 SET v = '[1.9, -5.02, 4]';

SELECT * FROM t1;

输出为:

sql 复制代码
--------------------------------------------------------------------------------
[1.89999998E+000,-5.01999998E+000,4.0E+000]
[1.89999998E+000,-5.01999998E+000,4.0E+000]
[1.89999998E+000,-5.01999998E+000,4.0E+000]
[1.89999998E+000,-5.01999998E+000,4.0E+000]
[1.89999998E+000,-5.01999998E+000,4.0E+000]
[1.89999998E+000,-5.01999998E+000,4.0E+000]
[1.89999998E+000,-5.01999998E+000,4.0E+000]

7 rows selected.

任务 5 - 对向量执行 DML 操作

包含向量的表上还允许执行其他 DML 操作,包括对向量本身的操作。

在此步骤中,我们将创建一个包含多列的表 - 包括一个向量列。我们还将向表中插入一些行。

sql 复制代码
CREATE TABLE IF NOT EXISTS t2
   ( id           NUMBER NOT NULL,
     name         VARCHAR2(32),
     v1           VECTOR,
                  PRIMARY KEY (id)
   );

DESC t2;

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 NAME                                               VARCHAR2(32)
 V1                                                 VECTOR(*, *)

将行插入到新创建的表中。

sql 复制代码
INSERT INTO t2 VALUES (1, 'A', '[1.1]'),
                      (2, 'B', '[2.2]'),
                      (3, 'C', '[3.3]'),
                      (4, 'D', '[4.4]'),
                      (5, 'E', '[5.5]');

SELECT * FROM t2;

        ID NAME       V1
---------- ---------- --------------------
         1 A          [1.10000002E+000]
         2 B          [2.20000005E+000]
         3 C          [3.29999995E+000]
         4 D          [4.4000001E+000]
         5 E          [5.5E+000]

现在让我们看看如何根据表中的另一列更新向量。

sql 复制代码
UPDATE t2
SET   v1 = '[2.9]'
WHERE id = 2;

SELECT * FROM t2
WHERE id = 2;

        ID NAME       V1
---------- ---------- ----------------------------------------
         2 B          [2.9000001E+000]

也可以删除表中包含向量的行。

sql 复制代码
DELETE FROM  t2
WHERE  id IN (1, 3);

SELECT * FROM t2;

        ID NAME       V1
---------- ---------- ----------------------------------------
         2 B          [2.9000001E+000]
         4 D          [4.4000001E+000]
         5 E          [5.5E+000]

任务 6 - 具有多个向量的表

可以创建一个包含多个向量的表。但最有可能的是,规范化表的每个表都有一个向量。

第一步,我们将创建一个包含多个向量的表。

sql 复制代码
CREATE TABLE IF NOT EXISTS t3
       ( id           NUMBER NOT NULL,
         name         VARCHAR2(32),
         v1           VECTOR,
         v2           VECTOR,
         v3           VECTOR,
                      PRIMARY KEY (id)
       );

DESC t3;

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 NAME                                               VARCHAR2(32)
 V1                                                 VECTOR(*, *)
 V2                                                 VECTOR(*, *)
 V3                                                 VECTOR(*, *)

接下来我们将在表中插入一行。

sql 复制代码
INSERT INTO t3 VALUES
       (1,
        'One',
        '[2.3, 4.5, 0.1]',
        '[1.3]',
        '[4.981, -6.3]'
       );

SELECT * FROM t3;


   ID NAME   V1                                                 V2                   V3
----- ------ -------------------------------------------------- -------------------- -----------------------------------
    1 One    [2.29999995E+000,4.5E+000,1.00000001E-001]         [1.29999995E+000]    [4.98099995E+000,-6.30000019E+000]

任务 7 - 对具有固定维度的向量执行操作

向量有两个组成部分:

  • 维度数
    • 定义后,维度数实际上成为检查约束。
  • 数字格式
    • Oracle 将根据需要转换数字。

您目前最多可以使用 64K 个维度,定义后,维度数实际上成为检查约束。

向量嵌入的维度数的一些示例:

  • OpenAI text-embedding-ada-002 = 1536 个维度
  • Cohere Embed-English-v2.0 = 4096 个维度
  • Cohere Embed-English-Light-v2.0 = 1024 个维度
  • Cohere Embed-Multilingual-v2.0 = 768 个维度
  • open-source all-MiniLM-L6-v2 = 384 个维度

让我们首先看看创建一个具有固定数字和数字格式向量的表有多么容易。

sql 复制代码
CREATE TABLE IF NOT EXISTS t4
                    ( v   VECTOR(3, FLOAT32) );

DESC t4;

 Name                                                              Null?    Type
 ----------------------------------------------------------------- -------- --------------------------------------------
 V                                                                          VECTOR(3, FLOAT32)

注意:观察最后 3 条插入语句抛出的错误消息。

sql 复制代码
-- 成功
INSERT INTO t4 VALUES ('[1.1, 2.2, 3.3]');
-- 成功
INSERT INTO t4 VALUES ('[1.2, 2.3, 3.4]');
-- 成功
INSERT INTO t4 VALUES ('[1.2, 2.3, 3.4]');
-- 错误:ORA-51803: Vector dimension count must match the dimension count specified in the column definition (actual: 1,
required: 3).
INSERT INTO t4 VALUES ('[1.3]');
-- 错误:ORA-51803: Vector dimension count must match the dimension count specified in the column definition (actual: 4,
required: 3).
INSERT INTO t4 VALUES ('[1.3, 2.4, 3.5, 4.1]');
-- 错误:ORA-51805: Vector is not properly formatted (dimension value 3 is either not a number or infinity).
INSERT INTO t4 VALUES ('[1.4, 2.5, a]');

任务 8 - 创建具有多维向量的表

可以创建一个具有不同 Vector 格式的表,在本例中我们将看到它是多么容易。

此表中将使用以下 Vector 格式:

  • vector(*, float64) 表示具有 float64 格式的任意维度
  • vector(5, *) 表示具有任意数字格式的五个维度
  • vector(*, *) 表示具有任意数字格式的任意维度
  • vector 表示具有 float32 格式的任意维度
  • vector(1, int8) 表示具有 int8 格式的一个维度
  • int8 是单个字节
sql 复制代码
CREATE TABLE IF NOT EXISTS t5
         ( v1        VECTOR(3, float32),
           v2        VECTOR(2, float64),
           v3        VECTOR(1, int8),
           v4        VECTOR(1, *),
           v5        VECTOR(*, float32),
           v6        VECTOR(*, *),
           v7        VECTOR
         );

DESC t5;

 Name                                                              Null?    Type
 ----------------------------------------------------------------- -------- --------------------------------------------
 V1                                                                         VECTOR(3, FLOAT32)
 V2                                                                         VECTOR(2, FLOAT64)
 V3                                                                         VECTOR(1, INT8)
 V4                                                                         VECTOR(1, *)
 V5                                                                         VECTOR(*, FLOAT32)
 V6                                                                         VECTOR(*, *)
 V7                                                                         VECTOR(*, *)

现在,让我们将数据插入到向量中:

sql 复制代码
INSERT INTO t5 VALUES ('[1.1, 2.2, 3.3]',
                       '[1.1, 2.2]',
                       '[7]',
                       '[9]',
                       '[1.1, 2.2, 3.3, 4.4, 5.5]',
                       '[1.1, 2.2]',
                       '[1.1, 2.2, 3.3, 4.4, 5.5, 6.6]'
                      );

SELECT * FROM t5;

V1                             V2                   V3
------------------------------ -------------------- -----------------------------------
V4
------------------------------------------------------------------------------------------------------------------------
V5
------------------------------------------------------------------------------------------------------------------------
V6
------------------------------------------------------------------------------------------------------------------------
V7
------------------------------------------------------------------------------------------------------------------------
[1.10000002E+000,2.20000005E+0 [1.1000000000000001E [7]
00,3.29999995E+000]            +000,2.2000000000000
                               002E+000]
[9.0E+000]
[1.10000002E+000,2.20000005E+000,3.29999995E+000,4.4000001E+000,5.5E+000]
[1.10000002E+000,2.20000005E+000]
[1.10000002E+000,2.20000005E+000,3.29999995E+000,4.4000001E+000,5.5E+000,6.5999999E+000]

任务 9 - 对向量执行 DDL 操作

允许对具有向量的表进行常规 DDL(数据定义语言)操作。

sql 复制代码
CREATE TABLE IF NOT EXISTS t6
          (
           id          NUMBER NOT NULL,
           name        VARCHAR2(32),
                       PRIMARY KEY (id)
          );

ALTER TABLE t6 ADD v1 VECTOR;
ALTER TABLE t6 ADD v2 VECTOR(2, float32);

DESC t6;

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 NAME                                               VARCHAR2(32)
 V1                                                 VECTOR(*, *)
 V2                                                 VECTOR(2, FLOAT32)

也可以从表中删除向量,甚至删除包含向量的整个表。

sql 复制代码
ALTER TABLE t6 DROP COLUMN v2;

DESC t6;

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 NAME                                               VARCHAR2(32)
 V1                                                 VECTOR(*, *)

DROP TABLE IF EXISTS t6;

还可以从另一个带有 Vector 的表创建一个带有 Vector 的表。在此示例中,我们使用 CTAS(将表创建为选择)操作。

sql 复制代码
CREATE TABLE IF NOT EXISTS t7
    AS SELECT * FROM t3;

DESC t7;

 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 NAME                                               VARCHAR2(32)
 V1                                                 VECTOR(*, *)
 V2                                                 VECTOR(*, *)
 V3                                                 VECTOR(*, *)

SELECT * FROM t7;

        ID NAME
---------- --------------------------------
V1
--------------------------------------------------------------------------------
V2
--------------------------------------------------------------------------------
V3
--------------------------------------------------------------------------------
         1 One
[2.29999995E+000,4.5E+000,1.00000001E-001]
[1.29999995E+000]
[4.98099995E+000,-6.30000019E+000]

任务 10 - 不允许的向量操作

无法在向量之间进行比较运算。在接下来的步骤中,所有三个语句都将失败,因为它们不被允许。

sql 复制代码
SELECT id, name FROM t2
WHERE  v1 IN (SELECT v FROM t1 WHERE t2.v1 = t1.v );

SELECT id, name FROM t2 WHERE v1 = '[2.9]';

SELECT id, name FROM t2 WHERE v1 = vector('[2.9, 0]', 2, float32);

错误都是一样的:

sql 复制代码
ERROR at line 1:
ORA-22848: cannot use VECTOR type as comparison key
Help: https://docs.oracle.com/error-help/db/ora-22848/

实验 2:矢量距离

本实验向您介绍 Vector_distance 函数。

  • Vector_distance() 是最重要的向量 SQL 函数,因为它支持相似性搜索。
  • 本练习涵盖了开始使用相似性搜索所需了解的概念和语法。

在本实验中,您将:

  • 使用 SQL vector() 构造函数创建向量
  • 使用 vector_distance() 函数返回两个向量之间的距离

任务 1:使用 SQL vector() 构造函数创建向量

二维图形有 X 轴和 Y 轴。X 轴是水平偏移。Y 轴是垂直偏移。指定 (X,Y) 坐标可确定二维图形/平面上的一个点。

您可以创建向量而不将它们插入向量列。这对于学习如何使用具有少量维度的向量很有用。通过 OpenAI 或 Cohere 等公司的嵌入模型创建的向量可以有数千个维度。

连接到您的数据库,并使用 SQL vector() 构造函数或 to_vector() 创建向量。VECTOR 是 TO_VECTOR 的同义词。

您需要指定向量值,并带有可选的数字维度和格式。以下构造函数表示上述二维坐标。在 Oracle 23ai 中,您不需要为 SQL 函数指定表。向量中的值将采用科学计数法格式。

sql 复制代码
SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100

SELECT VECTOR('[0,0]');
SELECT VECTOR('[10,0]');
-- 以下的2指定向量的维度,float32指定向量的格式,都可以省略
SELECT VECTOR('[0,5]', 2, float32);
SELECT VECTOR('[4,3]');
SELECT VECTOR('[5,-2]');
SELECT VECTOR('[-3,-4]');
SELECT VECTOR('[3.14,2.718]');
SELECT VECTOR('[-5.3,4.2]');
SELECT VECTOR('[-7,-9]');

输出为:

sql 复制代码
VECTOR('[0,0]')
--------------------------------------------------------------------------------
[0,0]

1 row selected.

SQL>
VECTOR('[10,0]')
--------------------------------------------------------------------------------
[1.0E+001,0]

1 row selected.

SQL>
VECTOR('[0,5]',2,FLOAT32)
--------------------------------------------------------------
[0,5.0E+000]

1 row selected.

SQL>
VECTOR('[4,3]')
--------------------------------------------------------------------------------
[4.0E+000,3.0E+000]

1 row selected.

SQL>
VECTOR('[5,-2]')
--------------------------------------------------------------------------------
[5.0E+000,-2.0E+000]

1 row selected.

SQL>
VECTOR('[-3,-4]')
--------------------------------------------------------------------------------
[-3.0E+000,-4.0E+000]

1 row selected.

SQL>
VECTOR('[3.14,2.718]')
--------------------------------------------------------------------------------
[3.1400001E+000,2.71799994E+000]

1 row selected.

SQL>
VECTOR('[-5.3,4.2]')
--------------------------------------------------------------------------------
[-5.30000019E+000,4.19999981E+000]

1 row selected.

SQL>

VECTOR('[-7,-9]')
--------------------------------------------------------------------------------
[-7.0E+000,-9.0E+000]

1 row selected.

任务 2:使用 vector_distance SQL 函数

vector_distance() SQL 函数返回两个向量之间的距离。例如,(0,0) 和 (10,0) 之间的距离为 10,即水平偏移量为 10,而垂直偏移量为零。

sql 复制代码
SELECT VECTOR_DISTANCE(
      VECTOR('[0, 0]'),
      VECTOR('[10, 0]'),
      EUCLIDEAN) DISTANCE;

  DISTANCE
----------
  1.0E+001

1 row selected.

SELECT TO_NUMBER(VECTOR_DISTANCE(
    VECTOR('[0, 0]', 2, FLOAT32),
    VECTOR('[0, 5]',2, FLOAT32),
    EUCLIDEAN)) DISTANCE;

  DISTANCE
----------
         5

SELECT TO_NUMBER(VECTOR_DISTANCE(
      VECTOR('[0, 0]', 2, FLOAT32),
      VECTOR('[4, 3]', 2, FLOAT32),
      EUCLIDEAN)) DISTANCE;

  DISTANCE
----------
         5

SELECT TO_NUMBER(VECTOR_DISTANCE(
      VECTOR('[0, 0]'),
      VECTOR('[3, 4]'),
      EUCLIDEAN)) DISTANCE;

  DISTANCE
----------
         5

SELECT TO_NUMBER(VECTOR_DISTANCE(
      VECTOR('[5, -2]', 2, FLOAT32),
      VECTOR('[-3, -4]',2, FLOAT32),
      EUCLIDEAN)) DISTANCE;

  DISTANCE
----------
8.24621105

SELECT TO_NUMBER(VECTOR_DISTANCE(
      VECTOR('[3.14, 2.718]'),
      VECTOR('[-5.3, 4.2]'),
      EUCLIDEAN)) DISTANCE;

  DISTANCE
----------
8.56912708

实验3:相似性搜索

本实验将引导您完成在多个向量之间执行相似性搜索的步骤。

对于相似性搜索,我们往往不关心两个向量之间的距离。相反,我们关心输入/查询向量与向量列中的向量集之间的结果集(按距离排序)。这意味着实际距离并不重要,结果集中距离的相对顺序才是重要的。

  • 结果集中的第一行将是与查询向量最接近或最相似的向量。
  • 结果集中的第二行将是与查询向量第二接近的向量。
  • 结果集中的第三行将是与查询向量第三接近的向量。

在本实验中,您将:

  • 设置一个包含实验中要使用的向量的表格。
  • 查找与给定向量最接近的向量。
  • 根据分组聚集的向量查找最接近的向量。

任务 1:设置一个包含样本向量的表格

创建一个表来存储向量:

sql 复制代码
CREATE TABLE IF NOT EXISTS vt1
         (id   NUMBER NOT NULL,
          v    VECTOR(2, FLOAT32),
               PRIMARY KEY (id)
         );

DESC vt1;

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 V                                                  VECTOR(2, FLOAT32)

将九个向量插入到表 vt1 中:

sql 复制代码
INSERT INTO vt1 VALUES (1, '[3, 3]'),  (2, '[5, 3]'),  (3, '[7, 3]'),
                       (4, '[3, 5]'),  (5, '[5, 5]'),  (6, '[7, 5]'),
                       (7, '[3, 7]'),  (8, '[5, 7]'),  (9, '[7, 7]');

COMMIT;

SELECT * FROM vt1 ORDER BY id;

        ID V
---------- ------------------------------
         1 [3.0E+000,3.0E+000]
         2 [5.0E+000,3.0E+000]
         3 [7.0E+000,3.0E+000]
         4 [3.0E+000,5.0E+000]
         5 [5.0E+000,5.0E+000]
         6 [7.0E+000,5.0E+000]
         7 [3.0E+000,7.0E+000]
         8 [5.0E+000,7.0E+000]
         9 [7.0E+000,7.0E+000]

9 rows selected.

任务 2:查找与给定向量最接近的向量

在我们的第一个例子中,我们将寻找下图 2 中红色"q"表示的三个最接近 (5,0) 的向量。

我们不关心实际距离,而是关心距离 (5,0) 最小(或最接近)的行的 ID,如上图 2 中的红色"q"所示。

ID 2 最接近,ID 1 和 3 距离相同,因此答案预计为:2、1、3 或 2、3、1。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY  vector_distance(vector('[5, 0]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID
----------
         2
         1
         3

查找下图 3 中红色"q"指示的三个最接近 (3,0) 的向量。

这次ID 1最接近,ID 3最远,所以答案预计是:1,2,3。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY  vector_distance(vector('[3, 0]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID
----------
         1
         2
         3

这次,让我们寻找下图 3 中红色"q"指示的三个最接近 (7,0) 的向量。

这次ID 3最近,ID 1最远,所以答案预计是:3,2,1。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY  vector_distance(vector('[7, 0]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID
----------
         3
         2
         1

查找下图 4 中红色"q"指示的三个最接近 (10,7) 的向量。

这次ID 9最近,ID 3最远,所以答案预计是:9,6,3。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY  vector_distance(vector('[10, 7]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID
----------
         9
         6
         3

查找下图 5 中红色"q"指示的三个最接近 (3,9) 的向量。

这次ID 7最接近,ID 4最远,所以答案预计是:7,8,4。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY  vector_distance(vector('[3, 9]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID
----------
         7
         8
         4

查找下图 6 中红色"q"指示的三个最接近 (0,0) 的向量。

这次 ID 1 是最接近的,而 ID 2 和 4 距离相同,所以答案预计是:1、4、2 或 1、2、4。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY  vector_distance(vector('[0, 0]'),  v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID
----------
         1
         2
         4

查找下图 7 中红色"q"标示的五个最接近 (5, 5) 的向量。

这次 ID 5 是最接近的,而 ID 2、4、6 和 8 的距离相同,因此答案预计为:首先是 5,然后是 2、4、6、8,顺序不限。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY  vector_distance(vector('[5, 5]'), v, EUCLIDEAN)
FETCH FIRST 5 ROWS ONLY;

        ID
----------
         5
         2
         8
         6
         4

查找下图 8 中红色"q"指示的四个最接近 (3.1, 6.9) 的向量。

这次 ID 7 是最接近的,而 ID 5 是最远的,所以答案预计是:7、4、8、5 或 7、8、4、5。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[3.1, 6.9]'), v, EUCLIDEAN)
FETCH FIRST 4 ROWS ONLY;

        ID
----------
         7
         4
         8
         5

按照与下图 9 中红色"q"指示的 (20, 1) 的接近程度对所有向量进行排序。

这次 ID 3 是最近的,而 ID 7 是距离最远的,所以答案预计以 ID 3 开始,以 ID 7 结束。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[20, 1]'), v, EUCLIDEAN)
FETCH FIRST 10 ROWS ONLY;

        ID
----------
         3
         6
         9
         2
         5
         8
         1
         4
         7

9 rows selected.

任务 3:根据分组聚类的向量查找最接近的向量

到目前为止,vector_distance 结果集取决于两个因素:

  • 查询向量相对于集群的位置,以特定向量或坐标为中心,即 (5,5)
  • 结果集中允许有多少行。

但是,矢量化数据通常由一组向量集群组成 - 并且数据往往不是均匀分布的。也可能有零个或多个数据集群。因此,向量集群往往表示相似数据的组。例如:地址、汽车类型、人名、报告或书籍等。

此示例有五个向量集群。因此,我们将在任务 1 中创建的表 vt1 中添加另外四个向量集群。您会注意到其中一个向量集群将包含负值(或坐标)。

将四个向量簇添加到表 vt1 中:

sql 复制代码
INSERT INTO vt1 VALUES (21, '[9, -1]'),
                       (22, '[10, -1]'),
                       (23, '[11, -1]'),
                       (24, '[9, -3]'),
                       (25, '[10, -4]'),
                       (26, '[12, -3]') ;

INSERT INTO vt1 VALUES (31, '[13, 6]'),
                       (32, '[14, 7]'),
                       (33, '[14, 4]'),
                       (34, '[16, 6]') ;

INSERT INTO vt1 VALUES (41, '[0, 7]'),
                       (42, '[1, 7]'),
                       (43, '[1, 6]'),
                       (44, '[0, 5]'),
                       (45, '[1, 5]') ;

INSERT INTO vt1 VALUES (51, '[5, 9]'),
                       (52, '[7, 9]'),
                       (53, '[6, 10]'),
                       (54, '[5, 11]'),
                       (55, '[7, 11]') ;

COMMIT ;

SELECT * FROM vt1;

        ID V
---------- ------------------------------
         1 [3.0E+000,3.0E+000]
         2 [5.0E+000,3.0E+000]
         3 [7.0E+000,3.0E+000]
         4 [3.0E+000,5.0E+000]
         5 [5.0E+000,5.0E+000]
         6 [7.0E+000,5.0E+000]
         7 [3.0E+000,7.0E+000]
         8 [5.0E+000,7.0E+000]
         9 [7.0E+000,7.0E+000]
        21 [9.0E+000,-1.0E+000]
        22 [1.0E+001,-1.0E+000]
        23 [1.1E+001,-1.0E+000]
        24 [9.0E+000,-3.0E+000]
        25 [1.0E+001,-4.0E+000]
        26 [1.2E+001,-3.0E+000]
        31 [1.3E+001,6.0E+000]
        32 [1.4E+001,7.0E+000]
        33 [1.4E+001,4.0E+000]
        34 [1.6E+001,6.0E+000]
        41 [0,7.0E+000]
        42 [1.0E+000,7.0E+000]
        43 [1.0E+000,6.0E+000]
        44 [0,5.0E+000]
        45 [1.0E+000,5.0E+000]
        51 [5.0E+000,9.0E+000]
        52 [7.0E+000,9.0E+000]
        53 [6.0E+000,1.0E+001]
        54 [5.0E+000,1.1E+001]
        55 [7.0E+000,1.1E+001]

29 rows selected.

查找下图中红色"q"指示的三个最接近 (16,4) 的向量。

我们期望看到 30 开头的 ID。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[16, 4]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID
----------
        33
        34
        31

查找下图中红色"q"指示的五个最接近 (7,-5) 的向量。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[7, -5]'), v, EUCLIDEAN)
FETCH FIRST 5 ROWS ONLY;

        ID
----------
        24
        25
        21
        22
        26

查找下图中红色"q"标示的五个最接近 (6, 10) 的向量。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[6, 10]'), v, EUCLIDEAN)
FETCH FIRST 5 ROWS ONLY;

        ID
----------
        53
        51
        55
        54
        52

在下图中查找最接近 (-1, 6) 的五个向量,用红色"q"表示。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[-1, 6]'), v, EUCLIDEAN)
FETCH FIRST 5 ROWS ONLY;

        ID
----------
        41
        44
        43
        42
        45

查找下图 15 中红色"q"指示的四个最接近 (6, 8) 的向量。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[6, 8]'), v, EUCLIDEAN)
FETCH FIRST 4 ROWS ONLY;

        ID
----------
         8
        52
        51
         9

查找下图 16 中红色"q"指示的四个最接近 (2.5, 8.5) 的向量。

sql 复制代码
SELECT id
FROM   vt1
ORDER  BY vector_distance(vector('[2.5, 8.5]'), v, EUCLIDEAN)
FETCH FIRST 4 ROWS ONLY;

        ID
----------
         7
        42
        51
         8

正如我们已经看到的,vector_distance() 函数按距离对结果进行排序。还可以向 SQL WHERE 子句添加其他谓词来过滤相似性搜索的结果。能够添加关系过滤器和表连接是一项非常强大的功能。

实验 4:属性过滤

在本实验中,我们将了解 Vector_Distance() 如何与其他 SQL WHERE 谓词结合使用。

任务 1:设置一个包含示例向量的表

在本实验中,我们将创建一个名为 VT2 的新表,但我们将使用上一个实验中创建的名为 VT1 的表来构建 VT2 表。本实验的第一步是创建一个带有矢量的表来映射不同的形状、颜色和大小,如下图所示:

创建一个表来存储向量:

sql 复制代码
DROP TABLE IF EXISTS vt2;

CREATE TABLE vt2 AS SELECT * FROM vt1;

ALTER TABLE vt2 ADD (vsize varchar2(16),
                     shape varchar2(16),
                     color varchar2(16)
                    );

DESC vt2;

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 V                                                  VECTOR(2, FLOAT32)
 VSIZE                                              VARCHAR2(16)
 SHAPE                                              VARCHAR2(16)
 COLOR                                              VARCHAR2(16)

在此步骤中,我们将设置用于属性过滤查询的表格的大小、形状和颜色。

sql 复制代码
/* 设置矢量大小 */
-- 12 rows updated.
UPDATE vt2
SET    vsize = 'Small'
WHERE  id IN (1, 4, 6, 8, 9, 21, 23, 26, 33, 44, 45, 52);

-- 10 rows updated.
UPDATE vt2
SET    vsize = 'Medium'
WHERE  id IN (5, 22, 25, 32, 34, 42, 43, 53, 54, 55);

-- 7 rows updated.
UPDATE vt2
SET    vsize = 'Large'
WHERE  id IN (2, 3, 7, 24, 31, 41, 51);

/* 设置矢量形状 */
-- 6 rows updated.
UPDATE vt2
SET    shape = 'Square'
WHERE  id IN (1, 3, 6, 42, 43, 54);

-- 8 rows updated.
UPDATE vt2
SET    shape = 'Triangle'
WHERE  id IN (2, 4, 7, 22, 31, 41, 44, 55);

-- 15 rows updated.
UPDATE vt2
SET    shape = 'Oval'
WHERE  id IN (5, 8, 9, 21, 23, 24, 25, 26, 32, 33, 34, 45, 51, 52, 53);

/* 设置矢量颜色 */
-- 12 rows updated.
UPDATE vt2
SET    color = 'Red'
WHERE  id IN (5, 8, 24, 26, 33, 34, 42, 44, 45, 53, 54, 55);

-- 6 rows updated.
UPDATE vt2
SET    color = 'Green'
WHERE  id IN (1, 4, 6, 21, 31, 52);

-- 11 rows updated.
UPDATE vt2
SET    color = 'Blue'
WHERE id IN (2, 3, 7, 9, 22, 23, 25, 32, 41, 43, 51);

COMMIT;

查看数据:

sql 复制代码
        ID VSIZE  SHAPE      COLOR            V
---------- ------ ---------- ---------------- ------------------------------
         1 Small  Square     Green            [3.0E+000,3.0E+000]
         2 Large  Triangle   Blue             [5.0E+000,3.0E+000]
         3 Large  Square     Blue             [7.0E+000,3.0E+000]
         4 Small  Triangle   Green            [3.0E+000,5.0E+000]
         5 Medium Oval       Red              [5.0E+000,5.0E+000]
         6 Small  Square     Green            [7.0E+000,5.0E+000]
         7 Large  Triangle   Blue             [3.0E+000,7.0E+000]
         8 Small  Oval       Red              [5.0E+000,7.0E+000]
         9 Small  Oval       Blue             [7.0E+000,7.0E+000]
        21 Small  Oval       Green            [9.0E+000,-1.0E+000]
        22 Medium Triangle   Blue             [1.0E+001,-1.0E+000]
        23 Small  Oval       Blue             [1.1E+001,-1.0E+000]
        24 Large  Oval       Red              [9.0E+000,-3.0E+000]
        25 Medium Oval       Blue             [1.0E+001,-4.0E+000]
        26 Small  Oval       Red              [1.2E+001,-3.0E+000]
        31 Large  Triangle   Green            [1.3E+001,6.0E+000]
        32 Medium Oval       Blue             [1.4E+001,7.0E+000]
        33 Small  Oval       Red              [1.4E+001,4.0E+000]
        34 Medium Oval       Red              [1.6E+001,6.0E+000]
        41 Large  Triangle   Blue             [0,7.0E+000]
        42 Medium Square     Red              [1.0E+000,7.0E+000]
        43 Medium Square     Blue             [1.0E+000,6.0E+000]
        44 Small  Triangle   Red              [0,5.0E+000]
        45 Small  Oval       Red              [1.0E+000,5.0E+000]
        51 Large  Oval       Blue             [5.0E+000,9.0E+000]
        52 Small  Oval       Green            [7.0E+000,9.0E+000]
        53 Medium Oval       Red              [6.0E+000,1.0E+001]
        54 Medium Square     Red              [5.0E+000,1.1E+001]
        55 Medium Triangle   Red              [7.0E+000,1.1E+001]

29 rows selected.

显示表 vt2 的不同形状、大小和颜色的汇总细目。

sql 复制代码
SELECT vsize, count(vsize)
FROM   vt2
GROUP  BY vsize;

VSIZE  COUNT(VSIZE)
------ ------------
Small            12
Large             7
Medium           10

SELECT color, COUNT(color)
FROM   vt2
GROUP  BY color;

COLOR            COUNT(COLOR)
---------------- ------------
Green                       6
Blue                       11
Red                        12

SELECT shape, COUNT(shape)
FROM   vt2
GROUP  BY shape;

SHAPE      COUNT(SHAPE)
---------- ------------
Square                6
Triangle              8
Oval                 15

任务 2:使用过滤查找与给定向量最接近的向量

在我们的第一个例子中,我们将寻找最接近 (16,3) 的三个向量。

sql 复制代码
SELECT id, vsize, shape, color,
       to_number(vector_distance(vector('[16, 3]'), v, EUCLIDEAN)) distance
FROM   vt2
WHERE  id > 30 AND id < 40
ORDER  BY vector_distance(vector('[16, 3]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR              DISTANCE
---------- ------ ---------- ---------------- ----------
        33 Small  Oval       Red              2.23606801
        34 Medium Oval       Red                       3
        31 Large  Triangle   Green             4.2426405

在此示例中,我们将寻找距离 (16,3) 最近的三个向量。但这次我们只寻找椭圆。

sql 复制代码
SELECT id, vsize, shape, color,
       to_number(vector_distance(vector('[16, 3]'), v, EUCLIDEAN)) distance
FROM   vt2
WHERE  id > 30 AND id < 40
AND    shape = 'Oval'
ORDER  BY vector_distance(vector('[16, 3]'), v, EUCLIDEAN)
FETCH FIRST 3 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR              DISTANCE
---------- ------ ---------- ---------------- ----------
        33 Small  Oval       Red              2.23606801
        34 Medium Oval       Red                       3
        32 Medium Oval       Blue             4.47213602

这次我们要寻找距离 (6,8) 最近的 10 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt2
ORDER  BY vector_distance(vector('[6, 8]'), v, EUCLIDEAN)
FETCH FIRST 10 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
         8 Small  Oval       Red
        52 Small  Oval       Green
        51 Large  Oval       Blue
         9 Small  Oval       Blue
        53 Medium Oval       Red
         5 Medium Oval       Red
        55 Medium Triangle   Red
        54 Medium Square     Red
         7 Large  Triangle   Blue
         6 Small  Square     Green

10 rows selected.

查找与 (6,8) 最接近的十个矢量,并按颜色进行过滤。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt2
WHERE  color = 'Red'
ORDER  BY vector_distance(vector('[6, 8]'), v, EUCLIDEAN)
FETCH FIRST 10 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
         8 Small  Oval       Red
        53 Medium Oval       Red
         5 Medium Oval       Red
        55 Medium Triangle   Red
        54 Medium Square     Red
        42 Medium Square     Red
        45 Small  Oval       Red
        44 Small  Triangle   Red
        33 Small  Oval       Red
        34 Medium Oval       Red

10 rows selected.

查找按颜色和形状过滤的十个最接近 (6,8) 的矢量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt2
WHERE  color = 'Red'
AND    shape = 'Oval'
ORDER  BY vector_distance(vector('[6, 8]'), v, EUCLIDEAN)
FETCH FIRST 10 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
         8 Small  Oval       Red
        53 Medium Oval       Red
         5 Medium Oval       Red
        45 Small  Oval       Red
        33 Small  Oval       Red
        34 Medium Oval       Red
        24 Large  Oval       Red
        26 Small  Oval       Red

8 rows selected.

通过颜色、形状和大小过滤,查找最接近 (6,8) 的十个矢量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt2
WHERE  color = 'Red'
AND    shape = 'Oval'
AND    vsize  = 'Small'
ORDER  BY vector_distance(vector('[6, 8]'), v, EUCLIDEAN)
FETCH FIRST 10 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
         8 Small  Oval       Red
        45 Small  Oval       Red
        33 Small  Oval       Red
        26 Small  Oval       Red

查找十个最接近 (6,8) 的矢量,这些矢量按颜色、形状和大小进行过滤,并且 ID 大于 10。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt2
WHERE  color = 'Red'
AND    shape = 'Oval'
AND    vsize  = 'Small'
AND    id    > 10
ORDER  BY vector_distance(vector('[6, 8]'), v, EUCLIDEAN)
FETCH FIRST 10 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        45 Small  Oval       Red
        33 Small  Oval       Red
        26 Small  Oval       Red

总结

通过使用 SQL WHERE 子句,您可以进一步过滤相似性搜索的结果。在其他(通常是非关系型) Vector 数据库中,使用 SQL WHERE 子句称为属性过滤。

实验 5:其他距离函数

到目前为止,我们已经将距离函数 vector_distance() 与欧几里得平方向量距离函数结合使用。

使用 Oracle AI Vector Search,您还可以使用其他类型的距离函数:

  • 余弦相似度
  • 点积
  • 曼哈顿距离
  • 汉明距离

注意:上面列出的其他距离函数的详细信息和用例可以参阅Oracle AI Vector Search 用户指南第 3 章。

向量嵌入模型将确定维度数,有时还确定距离函数:

  • Cohere embed-english-v2.0 = 4096 维度
  • Cohere embed-english-light-v2.0 = 1024 维度
  • Cohere embed-multilingual-v2.0 = 768 维度
  • OpenAI text-embedding-ada-002 = 1536 维度,并建议使用余弦相似度作为距离函数

vector_distance() 函数使用余弦相似度作为默认距离函数。但可以使用以下方法明确选择距离函数:

  • vector_distance(v1, v2, EUCLIDEAN);
  • vector_distance(v1, v2, COSINE);
  • vector_distance(v1, v2, DOT);
  • vector_distance(v1, v2, MANHATTAN);
  • vector_distance(v1,v2,HAMMING);

任务 1:设置一个包含示例向量的表格

本实验将创建一个名为 VT3 的新表,但我们将使用上一个实验中创建的名为 VT2 的表来构建 VT3 表。该表将包含映射到不同形状、颜色和大小的矢量,如下图所示:

sql 复制代码
DROP TABLE IF EXISTS vt3 ;

CREATE TABLE vt3 AS SELECT * FROM vt2;

SELECT * FROM vt3 ORDER BY 1;

        ID V                              VSIZE  SHAPE      COLOR
---------- ------------------------------ ------ ---------- ----------------
         1 [3.0E+000,3.0E+000]            Small  Square     Green
         2 [5.0E+000,3.0E+000]            Large  Triangle   Blue
         3 [7.0E+000,3.0E+000]            Large  Square     Blue
         4 [3.0E+000,5.0E+000]            Small  Triangle   Green
         5 [5.0E+000,5.0E+000]            Medium Oval       Red
         6 [7.0E+000,5.0E+000]            Small  Square     Green
         7 [3.0E+000,7.0E+000]            Large  Triangle   Blue
         8 [5.0E+000,7.0E+000]            Small  Oval       Red
         9 [7.0E+000,7.0E+000]            Small  Oval       Blue
        21 [9.0E+000,-1.0E+000]           Small  Oval       Green
        22 [1.0E+001,-1.0E+000]           Medium Triangle   Blue
        23 [1.1E+001,-1.0E+000]           Small  Oval       Blue
        24 [9.0E+000,-3.0E+000]           Large  Oval       Red
        25 [1.0E+001,-4.0E+000]           Medium Oval       Blue
        26 [1.2E+001,-3.0E+000]           Small  Oval       Red
        31 [1.3E+001,6.0E+000]            Large  Triangle   Green
        32 [1.4E+001,7.0E+000]            Medium Oval       Blue
        33 [1.4E+001,4.0E+000]            Small  Oval       Red
        34 [1.6E+001,6.0E+000]            Medium Oval       Red
        41 [0,7.0E+000]                   Large  Triangle   Blue
        42 [1.0E+000,7.0E+000]            Medium Square     Red
        43 [1.0E+000,6.0E+000]            Medium Square     Blue
        44 [0,5.0E+000]                   Small  Triangle   Red
        45 [1.0E+000,5.0E+000]            Small  Oval       Red
        51 [5.0E+000,9.0E+000]            Large  Oval       Blue
        52 [7.0E+000,9.0E+000]            Small  Oval       Green
        53 [6.0E+000,1.0E+001]            Medium Oval       Red
        54 [5.0E+000,1.1E+001]            Medium Square     Red
        55 [7.0E+000,1.1E+001]            Medium Triangle   Red

29 rows selected.

任务 2:使用替代距离函数查找与给定向量最接近的向量。

使用余弦相似度和欧几里得相似度作为向量距离函数,寻找最接近 (16,4) 的 4 个向量。

sql 复制代码
-- 余弦相似度
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY vector_distance( vector('[16, 4]'), v, COSINE)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
         3 Large  Square     Blue
        31 Large  Triangle   Green

-- 欧几里德相似性
        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
        31 Large  Triangle   Green
        32 Medium Oval       Blue

使用点积作为向量距离函数,寻找最接近 (16,4) 的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY vector_distance(vector('[16, 4]'), v, DOT)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        34 Medium Oval       Red
        32 Medium Oval       Blue
        33 Small  Oval       Red
        31 Large  Triangle   Green

使用曼哈顿作为向量距离函数,寻找最接近 (16,4) 的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY vector_distance(vector('[16, 4]'), v, MANHATTAN)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
        31 Large  Triangle   Green
        32 Medium Oval       Blue

使用汉明作为向量距离函数,寻找最接近 (16,4) 的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY vector_distance( vector('[16, 4]'), v, HAMMING)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
         1 Small  Square     Green
         4 Small  Triangle   Green

任务 3:使用替代向量距离函数查找最接近的向量

当使用欧几里得作为距离函数时,有四种方法可以实现此目的:欧几里得、欧几里得平方、L2_Distance 和速记。

距离函数的其他变体包括:

  • L1_DISTANCE(v1, v2) = MANHATTAN 距离
  • L2_DISTANCE(v1, v2) = 欧几里得距离
  • COSINE_DISTANCE(v1, v2) = 余弦相似度
  • INNER_PRODUCT(v1, v2) = 点积

使用 L1_DISTANCE 作为向量距离函数,查找距离 (16,4) 最近的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY L1_DISTANCE(vector('[16, 4]'), v)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
        31 Large  Triangle   Green
        32 Medium Oval       Blue

使用 L2_DISTANCE 作为向量距离函数,寻找最接近 (16,4) 的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY L2_DISTANCE(vector('[16, 4]'), v)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
        31 Large  Triangle   Green
        32 Medium Oval       Blue

使用 COSINE_DISTANCE 作为向量距离函数,查找最接近 (16,4) 的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY COSINE_DISTANCE( vector('[16, 4]'), v)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
         3 Large  Square     Blue
        31 Large  Triangle   Green

使用 INNER_PRODUCT 作为向量距离函数,寻找最接近 (16,4) 的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY INNER_PRODUCT(vector('[16, 4]'), v)
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        44 Small  Triangle   Red
        41 Large  Triangle   Blue
        45 Small  Oval       Red
        43 Medium Square     Blue

任务 4:使用简写语法查找最接近的向量

还可以使用简写语法来调用特定的向量距离函数。简写语法包括以下函数:

  • v1 <-> v2 = 欧几里得距离
  • v1 <=> v2 = 余弦相似度
  • v1 <#> v2 = 负点积

使用 <-> 作为向量距离函数,查找距离 (16,4) 最近的 4 个向量。

sql 复制代码
SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY vector('[16, 4]') <-> v
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
        31 Large  Triangle   Green
        32 Medium Oval       Blue

SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY vector('[16, 4]') <=> v
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        33 Small  Oval       Red
        34 Medium Oval       Red
         3 Large  Square     Blue
        31 Large  Triangle   Green

SELECT id, vsize, shape, color
FROM   vt3
ORDER  BY vector('[16, 4]') <#> v
FETCH FIRST 4 ROWS ONLY;

        ID VSIZE  SHAPE      COLOR
---------- ------ ---------- ----------------
        34 Medium Oval       Red
        32 Medium Oval       Blue
        33 Small  Oval       Red
        31 Large  Triangle   Green

总结

在本实验中,您已经了解了如何选择用于定位最近向量的距离函数。如果嵌入模型偏爱某个距离函数,那么您应该使用该距离函数。

您还了解了如何使用同义词甚至简写语法来调用向量距离函数。

除了支持不同的向量距离函数:余弦相似度、点积、欧几里得、曼哈顿距离和汉明距离之外,Oracle 还为您提供了四种使用欧几里得作为距离函数来搜索最近向量距离的方法:欧几里得、欧几里得平方、L2_Distance 和简写。

vector_distance(v1, v2, distance_function) 是向量距离最通用的语法。

向量距离没有正确或错误的语法。不同的向量距离语法在性能上也没有差异。您应该使用您最熟悉的语法。

实验 6:其他向量函数

到目前为止,我们重点介绍了 vector_distance() 函数,以及通过 SQL 显示查看输出。还有其他 SQL Vector 函数可用于管理 Vector 及其显示。

在本实验中,我们将探索提供有关 Vector 本身信息的其他函数。我们还将了解如何呈现 Vector 的输出,以便进行绑定以满足特定于应用程序的要求。

任务 1:用于操作向量的函数

将字符串转换为向量。

to_vector() 函数根据字符串创建向量。它相当于 vector() 构造函数。在此示例中,我们看到了两个将字符串转换为向量的示例。第一个示例解析二维数组,第二个示例解析三维数组。

sql 复制代码
SELECT to_vector('[34.6, 77.8]', 2, float32) FROM dual;

SELECT to_vector('[34.6, 77.8, -89.34]', 3, float32);

返回向量的范数:

sql 复制代码
SELECT vector_norm(vector('[4, 3]', 2, float32) );

SELECT vector_norm(vector('[4, 3]', 2, float64) );

SELECT vector_norm(vector('[4, 3]', 2, int8) );

输出都是:

sql 复制代码
VECTOR_NORM(VECTOR('[4,3]',2,INT8))
-----------------------------------
                           5.0E+000

确定向量中的维数。

sql 复制代码
-- 2
SELECT vector_dimension_count(vector('[34.6, 77.8]', 2, float64));

-- 3
SELECT vector_dimension_count(vector('[34.6, 77.8, 9]', 3, float32));

-- ORA-51803: Vector dimension count must match the dimension count specified in
the column definition (actual: 4, required: 3).
SELECT vector_dimension_count(vector('[34.6, 77.8, 9, 10]', 3, int8));

vector_dimension_format() 返回向量数字的格式

sql 复制代码
-- FLOAT64
SELECT vector_dimension_format(vector('[34.6, 77.8]', 2, float64));

-- FLOAT32
SELECT vector_dimension_format(vector('[34.6, 77.8, 9]', 3, float32));

-- ORA-51803: Vector dimension count must match the dimension count specified in
the column definition (actual: 4, required: 3).
SELECT vector_dimension_format(vector('[34.6, 77.8, 9, 10]', 3, int8));

任务 2:将向量转换为字符串或 CLOB

目前,python-oracledb 和 node-oracledb SQL 驱动程序支持对输入和输出进行向量的本机绑定。其他 SQL 驱动程序(如 JDBC 和 ODP.NET SQL)仅允许将向量绑定为字符串或 Clob。当 Oracle AI Vector Search 在 Oracle 23.4 中正式推出时,所有 Oracle SQL 驱动程序都应支持本机向量绑定。

较旧的 SQL 驱动程序 [21c 及之前版本] 要求您使用 vector() 或 to_vector() 函数显式转换向量输入,并通过 from_vector() 或 vector_serialize() 将向量输出转换为字符串或 Clob。

注意:如果您在 SQL*Plus、sqlcl 或 SQL Developer 中运行此实验,您将看不到输出中的明显差异,但您可以确信已执行向量转换。

使用 vector_serialize() 将向量转换为字符串或 CLOB。

sql 复制代码
SELECT vector_serialize(vector('[1.1, 2.2, 3.3]', 3, float32));

SELECT vector_serialize(vector('[1.1, 2.2, 3.3]', 3, float32)
       returning varchar2(1000));

SELECT vector_serialize(vector('[1.1, 2.2, 3.3]', 3, float32)
       returning clob);

输出都是:

sql 复制代码
--------------------------------------------------------------------------------
[1.10000002E+000,2.20000005E+000,3.29999995E+000]

使用 from_vector() 将 Vector 转换为字符串或 CLOB。

  • from_vector() 将 vector 转换为字符串或 clob
  • 它相当于 vector_serialize() 函数
sql 复制代码
SELECT from_vector(vector('[1.1, 2.2, 3.3]', 3, float32));

SELECT from_vector(vector('[1.1, 2.2, 3.3]', 3, float32) returning varchar2(1000));

SELECT from_vector(vector('[1.1, 2.2, 3.3]', 3, float32) returning clob);

输出都是:

sql 复制代码
[1.10000002E+000,2.20000005E+000,3.29999995E+000]
相关推荐
利瑞华33 分钟前
数据库索引:缺点与类型全解析
数据库·oracle
冷冷清清中的风风火火40 分钟前
本地部署DeepSeek的硬件配置建议
人工智能·ai
老周聊架构2 小时前
本地部署DeepSeek R1大模型
ai
QQ3596773453 小时前
Github 开源 AI 知识库推荐
人工智能·ai·知识库
ok0604 小时前
Oracle定时执行计划任务
数据库·oracle
怪怪王4 小时前
【编译器】-NIR
ai·chatgpt
Elastic 中国社区官方博客10 小时前
Elasticsearch 混合搜索 - Hybrid Search
大数据·人工智能·elasticsearch·搜索引擎·ai·语言模型·全文检索
9命怪猫11 小时前
DeepSeek底层揭秘——微调
人工智能·深度学习·神经网络·ai·大模型
d3soft12 小时前
deepseek清华大学第二版 如何获取 DeepSeek如何赋能职场应用 PDF文档 电子档(附下载)
ai·pdf·教程·deepseek·赋能职场
说是用户昵称已存在14 小时前
Pycharm+CodeGPT+Ollama+Deepseek
ide·python·ai·pycharm