非结构化数据向量检索

Lindorm向量索引旨在帮助您实现非结构化数据的检索分析。您可以通过AI算法提取非结构化数据的特征,并利用特征向量唯一标识非结构化数据。这些向量数据可以被Lindorm高性能地存储和检索。同时,Lindorm也支持向量数据与标量数据的混合检索。

背景信息

非结构化数据向量检索适用于以图搜图、声纹匹配、基于语义的文本检索和推荐(通过文本内容检索相近文本)、文件去重(通过文件指纹去除重复文本)、商品图片分析(例如在大量图片中,分析哪些图片包含了同一个商品)等场景。

前提条件

注意事项

搜索引擎Elasticsearch兼容版本暂不支持非结构化数据向量检索功能。

准备工作

创建如下主表:

CREATE TABLE vector_table (
   id varchar,
   name varchar,
   age integer,
   vector_column varchar,
   PRIMARY KEY(id));

创建向量索引

创建向量索引并将vector_column列定义为向量列。

CREATE SEARCH INDEX idx on vector_table (
  name,
  age,
  vector_column(type=vector)
) WITH (
indexState=ACTIVE, numShards=4,
dims=3, algorithm=HNSW, distance_method=L2, ef_construct=100, maximum_degree=16);
重要
  • 向量列的类型固定为VARCHAR类型。

  • 数据值固定为FLOAT类型数组,例如'[0.067985594, 0.94134957, 0.9174301]'

  • 一个向量索引只允许定义一个向量列。

参数说明

参数

是否必填

默认值

说明

type

不涉及

对于向量列,设置类型为vector。

dims

128

数组维度,等于特征向量的维度,取值范围 [1, 32768]。

algorithm

HNSW

向量索引的算法。支持FLAT和HNSW。HNSW以图结构构建向量检索的索引,FLAT采用暴力检索的方式计算距离。

distance_method

L2

向量距离函数。

取值如下:

  • L2:平方欧氏距离。常用于人脸识别等场景。计算方式:(x[1]-y[1])^2+(x[2]-y[2])^2+…+(x[n]-y[n])^2。

  • IP:向量内积。常用于推荐等场景。计算方式:x[1]*y[1]+x[2]*y[2]+…+x[n]*y[n]。

maximum_degree

16

HNSW算法的特定参数。取值范围:[2,100]。多数情况下,对于本身具有高维特征的数据集,算法中的maximum_degree参数取值越高,召回率越高;maximum_degree越低,性能越高。

说明

召回率的高低受多个参数影响,maximum_degree的取值无法直接决定召回率的高低。

ef_construct

100

HNSW算法的特定参数。 取值范围:[maximum_degree, 1000]。多数情况下,ef_construct的取值越大,索引构建越慢,索引精度越高,召回率越高。

说明

召回率的高低受多个参数影响,ef_construct的取值无法直接决定召回率的高低。

数据写入

非结构化数据向量检索的数据写入方式与普通的数据写入方式一致。

UPSERT INTO vector_table (id,name,age,vector_column) VALUES ('1', 'test', 19, '[0.067985594, 0.94134957, 0.9174301]');
UPSERT INTO vector_table (id,name,age,vector_column) VALUES ('2', 'test', 29, '[0.167985594, 0.24134957, 0.9174301]');
UPSERT INTO vector_table (id,name,age,vector_column) VALUES ('3', 'test2', 39, '[0.067885594, 0.94134957, 0.9174301]');
重要

写入的向量数组维度必须和定义的dims维度保持一致。

数据查询

向量列的查询通过ORDER BY vector_distance条件实现。即查找最相似的topK数据并默认按照_vector_score_字段降序排列,最靠前的为得分最高(距离最近或最相关)的向量数据。

纯向量查询

  • 一次性返回最相似的topK数据。

    SELECT id,_vector_score_ 
    FROM vector_table 
      ORDER BY vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301]')
    LIMIT 10;
    重要
    • _vector_score_为向量查询场景的内置字段,表示向量数据的相关度。_vector_score_的值越大,向量数据的相关度越高。如果想要在查询结果中获得向量数据的相关度,查询时请在select后添加_vector_score_字段。

    • _l_vector_topk_的值为指定topk的大小。未设置_l_vector_topk_参数时,limit的大小就是topK的大小。如果需要对topK的返回结果进行分页,可以通过下面(分页返回最相似的topK数据)的语法实现。如果topK不是很大,建议一次性返回所有topK数据。

    返回结果如下:

    +----+----------------+
    | id | _vector_score_ |
    +----+----------------+
    | 1  | 1              |
    | 3  | 1              |
    | 2  | 0.6666667      |
    +----+----------------+
  • 分页返回最相似的topK数据。

    SELECT /*+ _l_vector_topk_(100) */ id,_vector_score_ 
    FROM vector_table 
      ORDER BY vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301]')
    LIMIT 2 offset 1;

    返回结果如下:

    +----+----------------+
    | id | _vector_score_ |
    +----+----------------+
    | 3  | 1              |
    | 2  | 0.6666667      |
    +----+----------------+
  • 要求更高召回率。

    SELECT /*+ _l_vector_ef_search_(1000), _l_vector_topk_(20) */ id,_vector_score_ 
    FROM vector_table 
      ORDER BY vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301]')
    LIMIT 10;
    重要

    _l_vector_ef_search_的值越大,查询时扫描的数据越多,数据召回率越高,查询性能越低。建议您根据实际业务情况,设置合适的值。

    返回结果如下:

    +----+----------------+
    | id | _vector_score_ |
    +----+----------------+
    | 1  | 1              |
    | 3  | 1              |
    | 2  | 0.6666667      |
    +----+----------------+
  • 指定相似度阈值。

    SELECT /*+ _l_vector_topk_(100), _l_vector_minimum_score_('0.0000001') */ id,_vector_score_ 
    FROM vector_table 
    ORDER BY vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301]');

    _l_vector_minimum_score_代表相似度阈值,是以字符串表示的FLOAT类型数据,返回的向量数据相似度需要大于或等于该值。

    返回结果如下:

    +----+----------------+
    | id | _vector_score_ |
    +----+----------------+
    | 1  | 1              |
    | 3  | 1              |
    | 2  | 0.6666667      |
    +----+----------------+

融合查询

融合查询是指在一个查询语句中同时使用向量数据和结构化数据来进行查询和分析。

向量数据与结构化数据的融合查询以基于创建向量索引时设置的numShards参数的值为依据。每个索引表分片(Shard)会先根据向量的相似查询获取topK数据,再基于合并后的topK数据进行结构化数据过滤。在某些融合查询场景中,这种方式可能会影响最终召回率,可以通过增大numShards_l_vector_topk_的值,减少这种方式带来的影响。

SELECT /*+ _l_vector_topk_(100) */ id,_vector_score_ 
FROM vector_table 
WHERE
  age >18 and age <35 
ORDER BY 
  vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301]')
LIMIT 10;

向量数据导出

重要

仅23.12.0.0及以上版本的向量引擎(Tair实例)支持向量数据导出功能。使用前请确保已进行关联,具体操作,请参见关联向量引擎

Lindorm宽表引擎支持基于游标进行分页查询并导出向量数据。

查询语句需要包含以下四个参数:

参数

说明

_l_cursor_

查询时使用的游标。以HINT格式进行指定。首次查询时无需指定游标值,后续查询均需将_l_cursor_设置为上一次查询时返回的游标值。

offset

查询结果的偏移量。固定为0。

limit

指定查询结果集的返回行数。

_l_vector_minimum_score_

相似度阈值。以HINT格式进行指定。返回的向量数据相似度需大于或等于该值。

  • 首次使用游标分页进行查询。

    SELECT /*+ _l_cursor_ , _l_vector_minimum_score_('0.0000005') */ *
    FROM vector_table 
    ORDER BY vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301]')
    LIMIT 0,100;

    返回结果:

    +----+-------+-----+--------------------------------+----------------+------------------------------------------------------------------------------------------------------+
    | id | name  | age |         vector_column          | _vector_score_ |                                              _l_cursor_                                              |
    +----+-------+-----+--------------------------------+----------------+------------------------------------------------------------------------------------------------------+
    | 1  | test  | 19  | [0.067985594, 0.94134957,      | 1              | AUFBQUFCQVBUZGJILy8vLy8vLy8vLzhrQ0p4RC8vLy8vLy8vLy8rRFpneS8vLy8vLy8vLy8vNllJTkk3Ly8vLy8vLy8vL3c9PQ== |
    |    |       |     | 0.9174301]                     |                |                                                                                                      |
    | 3  | test2 | 39  | [0.067885594, 0.94134957,      | 1              | AUFBQUFCQVBUZGJILy8vLy8vLy8vLzhrQ0p4RC8vLy8vLy8vLy8rRFpneS8vLy8vLy8vLy8vNllJTkk3Ly8vLy8vLy8vL3c9PQ== |
    |    |       |     | 0.9174301]                     |                |                                                                                                      |
    | 2  | test  | 29  | [0.167985594, 0.24134957,      | 0.6666667      | AUFBQUFCQVBUZGJILy8vLy8vLy8vLzhrQ0p4RC8vLy8vLy8vLy8rRFpneS8vLy8vLy8vLy8vNllJTkk3Ly8vLy8vLy8vL3c9PQ== |
    |    |       |     | 0.9174301]                     |                |                                                                                                      |
    +----+-------+-----+--------------------------------+----------------+------------------------------------------------------------------------------------------------------+

    其中,_l_cursor_列为查询返回的游标值。

  • 二次查询。使用首次查询返回的游标值进行查询。

    SELECT /*+ _l_cursor_ ('AUFBQUFCQVBUZGJILy8vLy8vLy8vLzhrQ0p4RC8vLy8vLy8vLy8rRFpneS8vLy8vLy8vLy8vNllJTkk3Ly8vLy8vLy8vL3c9PQ=='), _l_vector_minimum_score_('0.0000005') */ *
    FROM vector_table 
    ORDER BY vector_distance(vector_column, '[0.067985594, 0.94134957, 0.9174301]')
    LIMIT 0,100;

    如果返回空数据,则表示已经没有更多的数据,查询结束。